<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\User;
use app\admin\model\Admin as AdminModel;
use app\admin\model\scanwork\Order;
use app\admin\model\scanwork\Allocation;
use app\admin\model\scanwork\Report;
use app\admin\model\scanwork\Product;
use app\admin\model\scanwork\ProductModel;
use app\admin\model\scanwork\Process;
use app\admin\model\scanwork\Config as ConfigModel;
use think\Db;
use think\Exception;

/**
 * 扫码工作API
 */
class Scanwork extends Api
{
    protected $noNeedLogin = [
        'adminLogin', 'checkToken', 'getOrders', 'getAllocations', 'getReports', 
        'getReportDetail', 'getProducts', 'getProcesses', 'getUsers', 
        'createAllocation', 'batchCreateAllocation', 'getModels', 'getOrderModels',
        'getOrderDetail', 'createOrder', 'updateOrder', 'deleteOrder', 'debugOrder',
        'uploadAuditImage', 'uploadAuditVideo', 'uploadReportImage', 'getActiveReports', 'getActiveReportDetail', 'auditActiveReport', 'auditReport',
        'getAllocationDetail', 'getProductList', 'createProduct', 'updateProduct', 'deleteProduct',
        'getProductModelList', 'createProductModel', 'updateProductModel', 'deleteProductModel',
        'getProcessList', 'createProcess', 'updateProcess', 'deleteProcess',
        'getProcessPriceList', 'createProcessPrice', 'updateProcessPrice', 'deleteProcessPrice', 'batchProcessPrice',
        'getAdminPermissions', 'getAdminList', 'createAdmin', 'updateAdmin', 'deleteAdmin', 'getAdminDetail',
        'getAvailableUsers', 'addProcessUsers', 'removeProcessUser', 'getProcessUsers', 'getTraceInfo',
        'getUserList', 'updateUser', 'deleteUser', 'changeUserPassword',
        'getProductionPlans', 'createProductionPlan', 'updateProductionPlan', 'deleteProductionPlan', 'getProductionPlanDetail',
        'getProductionPlanAllocations', 'allocateProductionPlan', 'batchAllocateProductionPlan', 'saveBatchAllocateProductionPlan',
        'getProductionPlanProgress', 'startProductionPlan', 'pauseProductionPlan', 'resumeProductionPlan', 'completeProductionPlan',
        'updateProductionPlanProgress', 'getProductionPlanStats', 'generateProductionPlanFromOrder', 'getOrderProducts',
        'getProductAvailableQuantity', 'setAdminPermissions', 'getDailyWorkRecords', 'getDailyWorkStats', 'auditDailyWorkReport', 'getSimpleUserList',
        'getQualityStandards', 'getQualityRecords', 'getPendingQualityReports', 'executeQualityCheck', 'getQualityRecordDetail', 'getQualityStatistics'
    ];
    protected $noNeedRight = ['adminLogin', 'checkToken', 'getAdminDetail', 'getAdminPermissionsInfo', 'getAllPermissions'];

    public function _initialize()
    {
        parent::_initialize();
        
        // 检查是否为管理员登录的方法
        $action = $this->request->action();
        $adminMethods = ['getOrders', 'getAllocations', 'getReports', 'getReportDetail', 'getProducts', 'getProcesses', 'getUsers', 'createAllocation', 'batchCreateAllocation', 'uploadAuditImage', 'uploadAuditVideo', 'getActiveReports', 'getActiveReportDetail', 'auditActiveReport', 'getAllocationDetail', 'getProductList', 'createProduct', 'updateProduct', 'deleteProduct', 'getProductModelList', 'createProductModel', 'updateProductModel', 'deleteProductModel', 'getProcessList', 'createProcess', 'updateProcess', 'deleteProcess', 'getProcessPriceList', 'createProcessPrice', 'updateProcessPrice', 'deleteProcessPrice', 'batchProcessPrice', 'getOrderProgressList', 'getProcessProgressStats', 'getOrderProgressDetail', 'getProgressFilterOptions', 'getAdminList', 'createAdmin', 'updateAdmin', 'deleteAdmin', 'getAdminDetail', 'getAllAdminPermissions', 'setAdminPermissions', 'getAvailableUsers', 'addProcessUsers', 'removeProcessUser', 'getProcessUsers', 'getUserList', 'updateUser', 'deleteUser', 'changeUserPassword', 'getProductionPlans', 'createProductionPlan', 'updateProductionPlan', 'deleteProductionPlan', 'getProductionPlanDetail', 'getProductionPlanAllocations', 'allocateProductionPlan', 'batchAllocateProductionPlan', 'saveBatchAllocateProductionPlan', 'getProductionPlanProgress', 'startProductionPlan', 'pauseProductionPlan', 'resumeProductionPlan', 'completeProductionPlan', 'updateProductionPlanProgress', 'getProductionPlanStats', 'generateProductionPlanFromOrder', 'getOrderProducts', 'auditReport', 'getDailyWorkRecords', 'getDailyWorkStats', 'auditDailyWorkReport', 'getSimpleUserList', 'getQualityStandards', 'getQualityRecords', 'getPendingQualityReports', 'executeQualityCheck', 'getQualityRecordDetail'];
        
        if (in_array($action, $adminMethods)) {
            // 验证管理员登录
            $adminInfo = session('admin_info');
            $adminToken = session('admin_token');
            
            \think\Log::info('_initialize - 方法: ' . $action . ', session admin_info: ' . json_encode($adminInfo));
            
            // 如果没有session，尝试通过token恢复
            if (!$adminInfo || !$adminToken) {
                $token = $this->request->header('Authorization');
                \think\Log::info('_initialize - 没有session，尝试通过token恢复，token: ' . $token);
                
                if ($token) {
                    // 处理Bearer token格式
                    if (strpos($token, 'Bearer ') === 0) {
                        $token = substr($token, 7);
                    }
                    
                    // 验证token并获取管理员信息
                    $admin = \app\admin\model\Admin::where('token', $token)->find();
                    
                    \think\Log::info('_initialize - token验证结果: ' . ($admin ? '找到管理员，状态: ' . $admin->status : '未找到管理员'));
                    
                    if ($admin && ($admin->status === 'normal' || $admin->status === 1 || $admin->status === '1' || $admin->status === 'active')) {
                        $adminInfo = [
                            'id' => $admin->id,
                            'username' => $admin->username,
                            'nickname' => $admin->nickname ?: $admin->username,
                            'avatar' => $admin->avatar ?: '',
                            'is_admin' => true
                        ];
                        $adminToken = $token;
                        
                        // 设置session
                        session('admin_info', $adminInfo);
                        session('admin_token', $adminToken);
                        
                        // 同时设置FastAdmin的session（保持兼容性）
                        session('admin', $admin->toArray());
                    } else {
                        // 如果token验证失败，记录日志
                        \think\Log::warning('Token验证失败 - 请求token: ' . $token);
                    }
                }
            }
            
            // 调试信息
            $headers = $this->request->header();
            $cookies = $this->request->cookie();
            \think\Log::info('API认证检查 - Action: ' . $action . ', SessionID: ' . session_id() . ', AdminInfo: ' . json_encode($adminInfo) . ', AdminToken: ' . $adminToken . ', Headers: ' . json_encode($headers) . ', Cookies: ' . json_encode($cookies));
            
            if (!$adminInfo || !$adminToken) {
                $this->error('请先登录', null, 401);
            }
            
            // 对于某些方法，跳过权限检查
            if (!in_array($action, ['getAdminPermissions', 'setAdminPermissions'])) {
                // 验证权限
                $this->checkPermission($action, $adminInfo['id']);
            }
        }
    }

    /**
     * 获取订单列表
     */
    public function getOrders()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $status = $this->request->get('status', '');
        
        $where = [];
        if ($status !== '') {
            $where[] = ['status', '=', $status];
        }
        
        $list = \app\admin\model\scanwork\Order::with(['orderModels.model.product'])
            ->where($where)
            ->order('id', 'desc')
            ->paginate($limit, false, ['page' => $page]);
        
        $this->success('获取成功', [
            'list' => $list->items(),
            'total' => $list->total(),
            'page' => $page,
            'limit' => $limit
        ]);
    }

    /**
     * 获取订单详情
     */
    public function getOrderDetail()
    {
        $orderId = $this->request->get('order_id');
        if (!$orderId) {
            $this->error('参数错误');
        }
        
        $order = \app\admin\model\scanwork\Order::with(['orderModels.model.product'])
            ->find($orderId);
        
        if (!$order) {
            $this->error('订单不存在');
        }
        
        $this->success('获取成功', $order);
    }

    /**
     * 创建订单
     */
    public function createOrder()
    {
        try {
            // 记录请求数据
            $data = $this->request->post();
            \think\Log::info('createOrder - 接收数据: ' . json_encode($data, JSON_UNESCAPED_UNICODE));
            
            if (empty($data['customer_name']) || empty($data['models'])) {
                \think\Log::error('createOrder - 参数不完整: customer_name=' . ($data['customer_name'] ?? '') . ', models=' . json_encode($data['models'] ?? [], JSON_UNESCAPED_UNICODE));
                $this->error('参数不完整');
            }
            
            // 处理models数据格式 - 支持对象和数组两种格式
            $models = $data['models'];
            if (is_object($models) || (is_array($models) && !isset($models[0]))) {
                // 如果是对象格式 {"6":{"quantity":"45","color":"红色"}}，转换为数组格式
                $modelsArray = [];
                foreach ($models as $modelId => $modelData) {
                    if (is_array($modelData) && isset($modelData['quantity'])) {
                        // 新格式：包含数量和颜色的对象
                        $modelsArray[] = [
                            'model_id' => intval($modelId),
                            'quantity' => intval($modelData['quantity']),
                            'color' => $modelData['color'] ?? ''
                        ];
                    } else {
                        // 旧格式：直接是数量值
                        $modelsArray[] = [
                            'model_id' => intval($modelId),
                            'quantity' => intval($modelData),
                            'color' => ''
                        ];
                    }
                }
                $data['models'] = $modelsArray;
                \think\Log::info('createOrder - 转换后的models数据: ' . json_encode($data['models'], JSON_UNESCAPED_UNICODE));
            }
            
            // 验证型号是否存在
            foreach ($data['models'] as $modelItem) {
                if (isset($modelItem['model_id'])) {
                    $model = \app\admin\model\scanwork\ProductModel::find($modelItem['model_id']);
                    if (!$model) {
                        \think\Log::error('createOrder - 型号不存在: model_id=' . $modelItem['model_id']);
                        $this->error('型号ID=' . $modelItem['model_id'] . '不存在');
                    }
                }
            }
            
            \think\Db::startTrans();
            try {
                // 生成订单号
                $orderNo = $this->generateOrderNo();
                \think\Log::info('createOrder - 生成订单号: ' . $orderNo);
                
                // 创建订单
                $orderData = [
                    'order_no' => $orderNo,
                    'customer_name' => $data['customer_name'],
                    'customer_phone' => $data['customer_phone'] ?? '',
                    'delivery_time' => $data['delivery_time'] ? strtotime($data['delivery_time']) : null,
                    'remark' => $data['remark'] ?? '',
                    'status' => 0,
                    'total_quantity' => 0,
                    'createtime' => time()
                ];
                \think\Log::info('createOrder - 订单数据: ' . json_encode($orderData, JSON_UNESCAPED_UNICODE));
                
                $order = \app\admin\model\scanwork\Order::create($orderData);
                \think\Log::info('createOrder - 订单创建成功，ID: ' . $order->id);
                
                // 保存订单型号
                $totalQuantity = 0;
                foreach ($data['models'] as $modelItem) {
                    if (isset($modelItem['model_id']) && isset($modelItem['quantity']) && $modelItem['quantity'] > 0) {
                        $orderModelData = [
                            'order_id' => $order->id,
                            'model_id' => $modelItem['model_id'],
                            'quantity' => $modelItem['quantity'],
                            'color' => $modelItem['color'] ?? ''
                        ];
                        \think\Log::info('createOrder - 订单型号数据: ' . json_encode($orderModelData, JSON_UNESCAPED_UNICODE));
                        
                        $orderModel = \app\admin\model\scanwork\OrderModel::create($orderModelData);
                        \think\Log::info('createOrder - 订单型号创建成功，ID: ' . $orderModel->id);
                        $totalQuantity += $modelItem['quantity'];
                    }
                }
                
                // 更新订单总数量
                $order->save(['total_quantity' => $totalQuantity]);
                \think\Log::info('createOrder - 订单总数量更新为: ' . $totalQuantity);
                
                \think\Db::commit();
                \think\Log::info('createOrder - 创建订单成功，订单ID: ' . $order->id);
                
                // 直接返回JSON响应，避免使用框架的success方法
                $result = [
                    'code' => 1,
                    'msg' => '创建成功',
                    'time' => time(),
                    'data' => null
                ];
                return json($result);
                
            } catch (\Exception $e) {
                \think\Db::rollback();
                // 记录详细的错误信息到日志
                \think\Log::error('createOrder - 数据库操作失败: ' . $e->getMessage() . ' - ' . $e->getFile() . ' on line ' . $e->getLine() . "\n" . $e->getTraceAsString());
                throw $e; // 重新抛出异常
            }
            
        } catch (\Exception $e) {
            // 记录详细的错误信息到日志
            \think\Log::error('createOrder - 创建订单失败: ' . $e->getMessage() . ' - ' . $e->getFile() . ' on line ' . $e->getLine() . "\n" . $e->getTraceAsString());
            $errorMsg = $e->getMessage() ?: '未知错误';
            $this->error('创建失败：' . $errorMsg);
        }
    }

    /**
     * 更新订单
     */
    public function updateOrder()
    {
        $orderId = $this->request->post('order_id');
        $data = $this->request->post();
        
        // 添加调试信息
        \think\Log::info('更新订单接收数据: ' . json_encode($data));
        
        if (!$orderId || empty($data['customer_name']) || empty($data['models'])) {
            $this->error('参数不完整');
        }
        
        $order = \app\admin\model\scanwork\Order::find($orderId);
        if (!$order) {
            $this->error('订单不存在');
        }
        
        // 处理models数据格式 - 支持对象和数组两种格式
        $models = $data['models'];
        if (is_object($models) || (is_array($models) && !isset($models[0]))) {
            // 如果是对象格式 {"6":{"quantity":"45","color":"红色"}}，转换为数组格式
            $modelsArray = [];
            foreach ($models as $modelId => $modelData) {
                if (is_array($modelData) && isset($modelData['quantity'])) {
                    // 新格式：包含数量和颜色的对象
                    $modelsArray[] = [
                        'model_id' => intval($modelId),
                        'quantity' => intval($modelData['quantity']),
                        'color' => $modelData['color'] ?? ''
                    ];
                } else {
                    // 旧格式：直接是数量值
                    $modelsArray[] = [
                        'model_id' => intval($modelId),
                        'quantity' => intval($modelData),
                        'color' => ''
                    ];
                }
            }
            $data['models'] = $modelsArray;
            \think\Log::info('updateOrder - 转换后的models数据: ' . json_encode($data['models'], JSON_UNESCAPED_UNICODE));
        }
        
        \think\Db::startTrans();
        try {
            // 更新订单基本信息
            $order->save([
                'customer_name' => $data['customer_name'],
                'customer_phone' => $data['customer_phone'] ?? '',
                'delivery_time' => $data['delivery_time'] ? strtotime($data['delivery_time']) : null,
                'remark' => $data['remark'] ?? '',
                'updatetime' => time()
            ]);
            
            // 删除原有订单型号
            \app\admin\model\scanwork\OrderModel::where('order_id', $orderId)->delete();
            
            // 保存新的订单型号
            $totalQuantity = 0;
            foreach ($data['models'] as $modelItem) {
                if (isset($modelItem['model_id']) && isset($modelItem['quantity']) && $modelItem['quantity'] > 0) {
                    \app\admin\model\scanwork\OrderModel::create([
                        'order_id' => $orderId,
                        'model_id' => $modelItem['model_id'],
                        'quantity' => $modelItem['quantity'],
                        'color' => $modelItem['color'] ?? ''
                    ]);
                    $totalQuantity += $modelItem['quantity'];
                }
            }
            
            // 更新订单总数量
            $order->save(['total_quantity' => $totalQuantity]);
            
            \think\Log::info('订单更新成功 - order_id: ' . $orderId . ', total_quantity: ' . $totalQuantity);
            \think\Db::commit();
            
            // 直接返回JSON响应，避免使用框架的success方法
            $result = [
                'code' => 1,
                'msg' => '更新成功',
                'time' => time(),
                'data' => null
            ];
            return json($result);
        } catch (\Exception $e) {
            \think\Db::rollback();
            // 记录详细的错误信息到日志
            \think\Log::error('更新订单失败: ' . $e->getMessage() . ' - ' . $e->getFile() . ' on line ' . $e->getLine() . "\n" . $e->getTraceAsString());
            $errorMsg = $e->getMessage() ?: '未知错误';
            $this->error('更新失败：' . $errorMsg);
        }
    }

    /**
     * 删除订单
     */
    public function deleteOrder()
    {
        try {
            $orderId = $this->request->post('order_id');
            \think\Log::info('deleteOrder - 接收数据: order_id=' . $orderId);
            
            if (!$orderId) {
                return json([
                    'code' => 0,
                    'msg' => '参数错误',
                    'time' => time(),
                    'data' => null
                ]);
            }
            
            $order = \app\admin\model\scanwork\Order::find($orderId);
            if (!$order) {
                return json([
                    'code' => 0,
                    'msg' => '订单不存在',
                    'time' => time(),
                    'data' => null
                ]);
            }
            
            // 检查是否有关联的分工分配
            $allocationCount = \app\admin\model\scanwork\Allocation::where('order_id', $orderId)->count();
            if ($allocationCount > 0) {
                return json([
                    'code' => 0,
                    'msg' => "订单【{$order->order_no}】下还有{$allocationCount}个分工分配，请先删除相关分工",
                    'time' => time(),
                    'data' => null
                ]);
            }
            
            \think\Db::startTrans();
            try {
                // 删除订单型号
                $deletedModels = \app\admin\model\scanwork\OrderModel::where('order_id', $orderId)->delete();
                \think\Log::info('deleteOrder - 删除订单型号数量: ' . $deletedModels);
                
                // 删除订单
                $order->delete();
                \think\Log::info('deleteOrder - 订单删除成功，订单ID: ' . $orderId);
                
                \think\Db::commit();
                
                return json([
                    'code' => 1,
                    'msg' => '删除成功',
                    'time' => time(),
                    'data' => null
                ]);
                
            } catch (\Exception $e) {
                \think\Db::rollback();
                \think\Log::error('deleteOrder - 数据库操作失败: ' . $e->getMessage() . ' - ' . $e->getFile() . ' on line ' . $e->getLine() . "\n" . $e->getTraceAsString());
                throw $e;
            }
            
        } catch (\Exception $e) {
            \think\Log::error('deleteOrder - 删除订单失败: ' . $e->getMessage() . ' - ' . $e->getFile() . ' on line ' . $e->getLine() . "\n" . $e->getTraceAsString());
            return json([
                'code' => 0,
                'msg' => '删除失败：' . ($e->getMessage() ?: '未知错误'),
                'time' => time(),
                'data' => null
            ]);
        }
    }

    /**
     * 生成订单号
     */
    private function generateOrderNo()
    {
        $prefix = 'ORD';
        $date = date('Ymd');
        $random = strtoupper(substr(md5(uniqid()), 0, 6));
        return $prefix . $date . $random;
    }

    /**
     * 获取分工任务列表
     */
    public function getAllocations()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $user_id = $this->request->get('user_id', '');
        $status = $this->request->get('status', '');
        
        $where = [];
        if ($user_id) {
            $where['user_id'] = $user_id;
        }
        if ($status !== '') {
            $where['status'] = $status;
        }
        
        $list = Allocation::with([
            'order',
            'model' => function($query) {
                $query->with('product');
            },
            'process',
            'user'
        ])
            ->where($where)
            ->order('id desc')
            ->paginate($limit, false, ['page' => $page]);
            
        // 处理列表数据，添加产品编号信息
        $items = $list->items();
        foreach ($items as &$item) {
            // 获取产品编号信息
            if ($item['work_type'] == 'piece' && $item['quantity'] > 0) {
                $productItems = \think\Db::name('scanwork_product_item')
                    ->where('allocation_id', $item['id'])
                    ->where('status', 0) // 未报工的产品编号
                    ->field('item_no')
                    ->select();
                
                $item['product_items'] = array_column($productItems, 'item_no');
                $item['product_items_count'] = count($productItems);
            } else {
                $item['product_items'] = [];
                $item['product_items_count'] = 0;
            }
        }
            
        $this->success('获取成功', [
            'total' => $list->total(),
            'list' => $items
        ]);
    }

    /**
     * 获取我的分工任务
     */
    public function getMyAllocations()
    {
        $user_id = $this->auth->id;
        if (!$user_id) {
            $this->error('请先登录');
        }
        
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $status = $this->request->get('status', '');
        
        $where = ['user_id' => $user_id];
        if ($status !== '') {
            $where['status'] = $status;
        }
        
        $list = Allocation::with(['order', 'model.product', 'process'])
            ->where($where)
            ->order('id desc')
            ->paginate($limit, false, ['page' => $page]);
            
        // 处理列表数据，添加产品编号信息
        $items = $list->items();
        foreach ($items as &$item) {
            // 获取产品编号信息
            if ($item['work_type'] == 'piece' && $item['quantity'] > 0) {
                $productItems = \think\Db::name('scanwork_product_item')
                    ->where('allocation_id', $item['id'])
                    ->where('status', 0) // 未报工的产品编号
                    ->field('item_no')
                    ->select();
                
                $item['product_items'] = array_column($productItems, 'item_no');
                $item['product_items_count'] = count($productItems);
            } else {
                $item['product_items'] = [];
                $item['product_items_count'] = 0;
            }
        }
            
        $this->success('获取成功', [
            'total' => $list->total(),
            'list' => $items
        ]);
    }

    /**
     * 获取分工分配详情
     */
    public function getAllocationDetail()
    {
        $allocation_id = $this->request->get('allocation_id');
        if (!$allocation_id) {
            $this->error('参数错误');
        }
        
        $allocation = Allocation::with([
            'order',
            'model' => function($query) {
                $query->with('product');
            },
            'process',
            'user'
        ])->find($allocation_id);
        
        if (!$allocation) {
            $this->error('分工分配不存在');
        }
        
        // 获取产品编号信息
        if ($allocation['work_type'] == 'piece' && $allocation['quantity'] > 0) {
            $productItems = \think\Db::name('scanwork_product_item')
                ->where('allocation_id', $allocation_id)
                ->field('id, item_no, status')
                ->select();
            
            $allocation['product_items'] = $productItems;
            $allocation['product_items_count'] = count($productItems);
            
            // 统计已报工和未报工的数量
            $reportedCount = 0;
            $unreportedCount = 0;
            foreach ($productItems as $item) {
                if ($item['status'] == 1) {
                    $reportedCount++;
                } else {
                    $unreportedCount++;
                }
            }
            $allocation['reported_items_count'] = $reportedCount;
            $allocation['unreported_items_count'] = $unreportedCount;
        } else {
            $allocation['product_items'] = [];
            $allocation['product_items_count'] = 0;
            $allocation['reported_items_count'] = 0;
            $allocation['unreported_items_count'] = 0;
        }
        
        $this->success('获取成功', $allocation);
    }

    /**
     * 提交报工
     */
    public function submitReport()
    {
        $allocation_id = $this->request->post('allocation_id');
        $quantity = $this->request->post('quantity', 0);
        $work_hours = $this->request->post('work_hours', 0);
        $remark = $this->request->post('remark', '');
        
        if (!$allocation_id) {
            $this->error('参数错误');
        }
        
        // 检查分工任务是否存在
                    $allocation = Allocation::find($allocation_id);
        if (!$allocation) {
            $this->error('分工任务不存在');
        }
        
        // 检查是否已报工
        $exists = Report::where('allocation_id', $allocation_id)->find();
        if ($exists) {
            $this->error('该任务已报工');
        }
        
        // 计算工资
        $wage = 0;
        if ($allocation->work_type == 'piece') {
            $wage = $quantity * $allocation->piece_price;
        } else {
            $wage = $work_hours * $allocation->time_price;
        }
        
        $data = [
            'allocation_id' => $allocation_id,
            'user_id' => $allocation->user_id,
            'quantity' => $quantity,
            'work_hours' => $work_hours,
            'wage' => $wage,
            'remark' => $remark,
            'status' => 0, // 待审核
            'createtime' => time()
        ];
        
        Db::startTrans();
        try {
            $report = Report::create($data);
            
            // 更新分工任务状态
            $allocation->status = 1; // 已报工
            $allocation->save();
            
            Db::commit();
            $this->success('报工成功', $report);
        } catch (Exception $e) {
            Db::rollback();
            $this->error('报工失败：' . $e->getMessage());
        }
    }

    /**
     * 上传报工图片
     */
    public function uploadReportImage()
    {
        $report_id = $this->request->post('report_id');
        $file = $this->request->file('image');
        
        if (!$report_id || !$file) {
            $this->error('参数错误');
        }
        
        // 检查报工记录是否存在
        $report = Report::find($report_id);
        if (!$report) {
            $this->error('报工记录不存在');
        }
        
        // 上传图片
        $info = $file->validate(['size' => 10240 * 1024, 'ext' => 'jpg,jpeg,png,gif'])
            ->move('uploads/report/');
            
        if (!$info) {
            $this->error('图片上传失败：' . $file->getError());
        }
        
        $filename = $info->getSaveName();
        $url = ConfigModel::getSiteDomain() . '/uploads/report/' . $filename;
        
        // 保存图片记录
        $data = [
            'report_id' => $report_id,
            'image_url' => $url,
            'createtime' => time()
        ];
        
        Db::name('scanwork_report_image')->insert($data);
        
        $this->success('上传成功', ['url' => $url]);
    }

    /**
     * 上传审核图片
     */
    public function uploadAuditImage()
    {
        // 添加调试日志
        \think\Log::info('uploadAuditImage - 开始处理图片上传');
        \think\Log::info('uploadAuditImage - POST数据: ' . json_encode($this->request->post(), JSON_UNESCAPED_UNICODE));
        \think\Log::info('uploadAuditImage - FILES数据: ' . json_encode($this->request->file(), JSON_UNESCAPED_UNICODE));
        
        $report_id = $this->request->post('report_id');
        $item_no = $this->request->post('item_no'); // 产品编号
        $report_type = $this->request->post('report_type', 'normal'); // normal: 普通报工, active: 主动报工
        
        \think\Log::info('uploadAuditImage - report_id: ' . $report_id . ', item_no: ' . $item_no . ', report_type: ' . $report_type);
        
        if (!$report_id) {
            \think\Log::error('uploadAuditImage - 参数错误: report_id=' . $report_id);
            $this->error('参数错误');
        }
        
        if (!$item_no) {
            \think\Log::error('uploadAuditImage - 参数错误: item_no=' . $item_no);
            $this->error('请指定产品编号');
        }
        
        // 处理文件上传 - 支持多种上传方式
        $file = null;
        $files = $this->request->file();
        
        if (!empty($files['audit_images'])) {
            $file = $files['audit_images'];
        } elseif (!empty($files)) {
            // 如果没有audit_images字段，取第一个文件
            $file = reset($files);
        }
        
        if (!$file) {
            \think\Log::error('uploadAuditImage - 没有接收到文件');
            $this->error('没有接收到文件');
        }
        
        // 确保文件是数组格式
        if (!is_array($file)) {
            $file = [$file];
        }
        
        $uploadedUrls = [];
        
        foreach ($file as $singleFile) {
            if (!$singleFile->isValid()) {
                \think\Log::error('uploadAuditImage - 文件验证失败: ' . $singleFile->getError());
                $this->error('文件上传失败: ' . $singleFile->getError());
            }
            
            // 先保存到本地
            $info = $singleFile->validate(['size' => 10240 * 1024, 'ext' => 'jpg,jpeg,png,gif'])
                ->move('uploads/audit/');
                
            if (!$info) {
                \think\Log::error('uploadAuditImage - 文件保存失败: ' . $singleFile->getError());
                $this->error($singleFile->getError());
            }
            
            $filename = $info->getSaveName();
            $localPath = 'uploads/audit/' . $filename;
            
            // 设置文件权限为755
            $fullPath = ROOT_PATH . 'public' . DS . $localPath;
            if (file_exists($fullPath)) {
                chmod($fullPath, 0755);
                \think\Log::info('uploadAuditImage - 文件权限已设置为755: ' . $fullPath);
            }
            $localUrl = ConfigModel::getSiteDomain() . '/' . $localPath;
            
            // 上传到云存储（根据默认配置选择存储提供商）
            \think\Log::info('=== 开始上传审核图片到云存储 ===');
            \think\Log::info('文件名: ' . $filename);
            \think\Log::info('本地路径: ' . $localPath);
            $cloudUrl = $this->uploadToCloudStorage($localPath, $filename);
            \think\Log::info('云存储上传结果：' . ($cloudUrl ?: '失败'));
            \think\Log::info('=== 云存储上传结束 ===');
            
            if ($cloudUrl) {
                // 使用云存储URL作为主要URL
                $url = $cloudUrl;
                \think\Log::info('审核图片已上传到云存储：' . $cloudUrl . '，本地备份：' . $localUrl);
            } else {
                \think\Log::info('云存储上传失败，使用本地URL：' . $localUrl);
                // 如果云存储上传失败，使用本地URL
                $url = $localUrl;
            }
            
            $uploadedUrls[] = $url;
            
            // 根据报工类型保存到不同的表
            if ($report_type == 'active') {
                // 主动报工审核图片
                $data = [
                    'active_report_id' => $report_id,
                    'image_url' => $url,
                    'image_type' => 2, // 2: 审核图片
                    'item_no' => $item_no, // 保存产品编号
                    'createtime' => time()
                ];
                
                Db::name('scanwork_active_report_image')->insert($data);
                \think\Log::info('uploadAuditImage - 主动报工图片保存成功: ' . $url . ', item_no: ' . $item_no);
            } else {
                // 普通报工审核图片 - 按产品编号保存
                $adminInfo = session('admin_info');
                $adminId = $adminInfo['id'] ?? 1;
                
                // 查找产品编号对应的item_id
                $item = Db::name('scanwork_product_item')->where('item_no', $item_no)->find();
                if ($item) {
                    // 保存到产品审核图片表
                    $data = [
                        'item_id' => $item['id'],
                        'report_id' => $report_id,
                        'image_url' => $url,
                        'cloud_file_id' => null, // 不存储文件名，因为字段类型是int
                        'upload_user_id' => $adminId,
                        'audit_status' => 0, // 待审核
                        'audit_reason' => '',
                        'createtime' => time()
                    ];
                    
                    Db::name('scanwork_item_audit_image')->insert($data);
                    \think\Log::info('uploadAuditImage - 产品编号审核图片保存成功: ' . $url . ', item_no: ' . $item_no);
                } else {
                    \think\Log::error('uploadAuditImage - 未找到产品编号: ' . $item_no);
                    $this->error('产品编号不存在');
                }
            }
        }
        
        \think\Log::info('uploadAuditImage - 上传完成，返回URL: ' . json_encode($uploadedUrls));
        $this->success('上传成功', ['url' => $uploadedUrls[0]]); // 返回第一个URL
    }

    /**
     * 上传审核视频
     */
    public function uploadAuditVideo()
    {
        // 添加调试日志
        \think\Log::info('uploadAuditVideo - 开始处理视频上传');
        \think\Log::info('uploadAuditVideo - POST数据: ' . json_encode($this->request->post(), JSON_UNESCAPED_UNICODE));
        \think\Log::info('uploadAuditVideo - FILES数据: ' . json_encode($this->request->file(), JSON_UNESCAPED_UNICODE));
        
        $report_id = $this->request->post('report_id');
        $item_no = $this->request->post('item_no'); // 产品编号
        $report_type = $this->request->post('report_type', 'normal'); // normal: 普通报工, active: 主动报工
        
        \think\Log::info('uploadAuditVideo - report_id: ' . $report_id . ', item_no: ' . $item_no . ', report_type: ' . $report_type);
        
        if (!$report_id) {
            \think\Log::error('uploadAuditVideo - 参数错误: report_id=' . $report_id);
            $this->error('参数错误');
        }
        
        if (!$item_no) {
            \think\Log::error('uploadAuditVideo - 参数错误: item_no=' . $item_no);
            $this->error('请指定产品编号');
        }
        
        // 处理文件上传 - 支持多种上传方式
        $file = null;
        $files = $this->request->file();
        
        if (!empty($files['audit_videos'])) {
            $file = $files['audit_videos'];
        } elseif (!empty($files)) {
            // 如果没有audit_videos字段，取第一个文件
            $file = reset($files);
        }
        
        if (!$file) {
            \think\Log::error('uploadAuditVideo - 没有接收到文件');
            $this->error('没有接收到文件');
        }
        
        // 确保文件是数组格式
        if (!is_array($file)) {
            $file = [$file];
        }
        
        $uploadedUrls = [];
        
        foreach ($file as $singleFile) {
            if (!$singleFile->isValid()) {
                \think\Log::error('uploadAuditVideo - 文件验证失败: ' . $singleFile->getError());
                $this->error('文件上传失败: ' . $singleFile->getError());
            }
            
            // 先保存到本地
            $info = $singleFile->validate(['size' => 100 * 1024 * 1024, 'ext' => 'mp4,avi,mov,wmv,flv,3gp,webm'])
                ->move('uploads/audit_video/');
                
            if (!$info) {
                \think\Log::error('uploadAuditVideo - 文件保存失败: ' . $singleFile->getError());
                $this->error($singleFile->getError());
            }
            
            $filename = $info->getSaveName();
            $localPath = 'uploads/audit_video/' . $filename;
            
            // 设置文件权限为755
            $fullPath = ROOT_PATH . 'public' . DS . $localPath;
            if (file_exists($fullPath)) {
                chmod($fullPath, 0755);
                \think\Log::info('uploadAuditVideo - 文件权限已设置为755: ' . $fullPath);
            }
            $localUrl = ConfigModel::getSiteDomain() . '/' . $localPath;
            
            // 上传到云存储（根据默认配置选择存储提供商）
            \think\Log::info('=== 开始上传审核视频到云存储 ===');
            \think\Log::info('文件名: ' . $filename);
            \think\Log::info('本地路径: ' . $localPath);
            $cloudUrl = $this->uploadToCloudStorage($localPath, $filename);
            \think\Log::info('云存储上传结果：' . ($cloudUrl ?: '失败'));
            \think\Log::info('=== 云存储上传结束 ===');
            
            if ($cloudUrl) {
                // 使用云存储URL作为主要URL
                $url = $cloudUrl;
                \think\Log::info('审核视频已上传到云存储：' . $cloudUrl);
                
                // 云存储上传成功，删除本地文件以节省空间
                if (file_exists($fullPath)) {
                    unlink($fullPath);
                    \think\Log::info('本地视频文件已删除：' . $fullPath);
                }
            } else {
                \think\Log::info('云存储上传失败，使用本地URL：' . $localUrl);
                // 如果云存储上传失败，使用本地URL
                $url = $localUrl;
            }
            
            $uploadedUrls[] = $url;
            
            // 根据报工类型保存到不同的表
            if ($report_type == 'active') {
                // 主动报工审核视频
                $data = [
                    'active_report_id' => $report_id,
                    'video_url' => $url,
                    'video_type' => 2, // 2: 审核视频
                    'item_no' => $item_no, // 保存产品编号
                    'createtime' => time()
                ];
                
                Db::name('scanwork_active_report_video')->insert($data);
                \think\Log::info('uploadAuditVideo - 主动报工视频保存成功: ' . $url . ', item_no: ' . $item_no);
            } else {
                // 普通报工审核视频 - 按产品编号保存
                $adminInfo = session('admin_info');
                $adminId = $adminInfo['id'] ?? 1;
                
                // 查找产品编号对应的item_id
                $item = Db::name('scanwork_product_item')->where('item_no', $item_no)->find();
                if ($item) {
                    // 保存到产品审核图片表（支持视频）
                    $data = [
                        'item_id' => $item['id'],
                        'report_id' => $report_id,
                        'image_url' => $url, // 使用image_url字段存储视频URL
                        'cloud_file_id' => null, // 不存储文件名，因为字段类型是int
                        'upload_user_id' => $adminId,
                        'audit_status' => 0, // 待审核
                        'audit_reason' => '',
                        'createtime' => time()
                    ];
                    
                    Db::name('scanwork_item_audit_image')->insert($data);
                    \think\Log::info('uploadAuditVideo - 产品编号审核视频保存成功: ' . $url . ', item_no: ' . $item_no);
                } else {
                    \think\Log::error('uploadAuditVideo - 未找到产品编号: ' . $item_no);
                    $this->error('产品编号不存在');
                }
            }
        }
        
        \think\Log::info('uploadAuditVideo - 上传完成，返回URL: ' . json_encode($uploadedUrls));
        $this->success('上传成功', ['url' => $uploadedUrls[0]]); // 返回第一个URL
    }

    /**
     * 获取报工列表（管理员）
     */
    public function getReports()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $status = $this->request->get('status', '');
        
        $where = [];
        if ($status !== '') {
            $where['status'] = $status;
        }
        
        $list = Report::with([
            'allocation' => function($query) {
                $query->with([
                    'order',
                    'model' => function($q) {
                        $q->with('product');
                    },
                    'process'
                ]);
            },
            'user'
        ])
            ->where($where)
            ->order('id desc')
            ->paginate($limit, false, ['page' => $page]);
            
        // 处理列表数据，确保关联数据正确
        $items = $list->items();
        foreach ($items as &$item) {
            // 如果allocation关联数据为空，尝试直接获取
            if (empty($item['allocation']['order']['order_no']) || empty($item['allocation']['model']['name'])) {
                $allocation = \app\admin\model\scanwork\Allocation::with(['order', 'model.product', 'process'])
                    ->find($item['allocation_id']);
                if ($allocation) {
                    $item['allocation'] = $allocation;
                }
            }
            
            // 添加产品编号信息
            if ($item['item_nos']) {
                $itemNos = json_decode($item['item_nos'], true) ?: [];
                $item['item_no'] = implode(', ', $itemNos);
            } else {
                $item['item_no'] = '';
            }
        }
            
        $this->success('获取成功', [
            'total' => $list->total(),
            'list' => $items
        ]);
    }

    /**
     * 获取主动报工列表
     */
    public function getActiveReports()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $status = $this->request->get('status', '');
        
        $where = [];
        if ($status !== '') {
            $where['status'] = $status;
        }
        
        // 使用模型查询，避免表名问题
        $list = \app\admin\model\ActiveReport::with([
            'user',
            'order',
            'model.product',
            'process'
        ])
            ->where($where)
            ->order('id desc')
            ->paginate($limit, false, ['page' => $page]);
            
        $items = $list->items();
        foreach ($items as &$item) {
            $item['createtime_text'] = date('Y-m-d H:i:s', $item['createtime']);
            // 确保关联数据正确
            $item['user_name'] = $item['user']['nickname'] ?? '';
            $item['order_no'] = $item['order']['order_no'] ?? '';
            $item['product_name'] = $item['model']['product']['name'] ?? '';
            $item['model_name'] = $item['model']['name'] ?? '';
            $item['process_name'] = $item['process']['name'] ?? '';
        }
            
        $this->success('获取成功', [
            'total' => $list->total(),
            'list' => $items
        ]);
    }

    /**
     * 审核报工
     */
    public function auditReport()
    {
        
        $report_id = $this->request->post('report_id');
        $status = $this->request->post('status'); // 1通过 2拒绝
        $audit_reason = $this->request->post('audit_reason', '');
        $audit_data = $this->request->post('audit_data'); // 按产品编号的审核数据
        $admin_id = $this->request->post('admin_id', 1); // 管理员ID，默认为1
        
        if (!$report_id || !in_array($status, ['1', '2'])) {
            $this->error('参数错误');
        }
        
        $report = Report::find($report_id);
        if (!$report) {
            $this->error('报工记录不存在');
        }
        
        // 处理上传的审核图片
        $uploadedImages = [];
        $files = $this->request->file('audit_images');
        if ($files) {
            if (!is_array($files)) {
                $files = [$files];
            }
            
            foreach ($files as $file) {
                if ($file && $file->isValid()) {
                    $info = $file->validate(['size' => 10240 * 1024, 'ext' => 'jpg,jpeg,png,gif'])
                        ->move('uploads/audit/');
                    if ($info) {
                        $filename = $info->getSaveName();
                        $uploadedImages[] = ConfigModel::getSiteDomain() . '/uploads/audit/' . $filename;
                    }
                }
            }
        }
        
        Db::startTrans();
        try {
            // 处理按产品编号的审核（计件报工）
            if (!empty($audit_data) && is_array($audit_data) && $report['allocation']['work_type'] == 'piece') {
                foreach ($audit_data as $itemNo => $auditInfo) {
                    $itemStatus = $auditInfo['status'];
                    $itemReason = $auditInfo['reason'] ?? '';
                    
                    // 更新产品编号的审核状态
                    $itemIds = Db::name('scanwork_product_item')
                        ->where('allocation_id', $report['allocation_id'])
                        ->where('item_no', $itemNo)
                        ->column('id');
                    
                    if (!empty($itemIds)) {
                        Db::name('scanwork_item_report_image')
                            ->where('report_id', $report_id)
                            ->where('item_id', 'in', $itemIds)
                            ->update([
                                'audit_status' => $itemStatus,
                                'audit_reason' => $itemReason,
                                'audit_time' => time()
                            ]);
                    }
                }
            }
            
            $report->status = $status;
            if ($status == '2') {
                $report->audit_reason = $audit_reason;
            }
            
            // 如果审核通过，计算工资
            if ($status == '1') {
                // 通过allocation获取process_id和model_id
                $allocation = \app\admin\model\scanwork\Allocation::find($report->allocation_id);
                if ($allocation) {
                    // 获取工序工价
                    $processPrice = \app\admin\model\scanwork\ProcessPrice::where([
                        'process_id' => $allocation->process_id,
                        'model_id' => $allocation->model_id
                    ])->find();
                    
                    \think\Log::info('工资计算 - process_id: ' . $allocation->process_id . ', model_id: ' . $allocation->model_id);
                    \think\Log::info('工序工价: ' . json_encode($processPrice, JSON_UNESCAPED_UNICODE));
                    
                    if ($processPrice) {
                        $wage = $report->quantity * $processPrice->price;
                        $report->wage = $wage;
                        \think\Log::info('计算工资: ' . $report->quantity . ' * ' . $processPrice->price . ' = ' . $wage);
                    } else {
                        // 如果没有找到工价，使用默认工价或从allocation中获取
                        $wage = $report->quantity * $allocation->getPriceAttr(null, $allocation->toArray());
                        $report->wage = $wage;
                        \think\Log::info('使用allocation工价计算: ' . $wage);
                    }
                }
            }
            
            // 设置审核信息
            $report->audit_user_id = $admin_id;
            $report->audit_time = time();
            
            $report->save();
            
            // 保存审核图片
            if (!empty($uploadedImages)) {
                $adminId = $admin_id; // 使用传入的管理员ID
                $data = [];
                foreach ($uploadedImages as $image) {
                    $data[] = [
                        'report_id' => $report_id,
                        'image_url' => $image,
                        'upload_user_id' => $adminId,
                        'createtime' => time()
                    ];
                }
                Db::name('scanwork_audit_image')->insertAll($data);
            }
            
            // 审核通过后创建溯源码
            if ($status == '1') {
                $this->createTraceCodeAfterAudit($report);
            }
            
            Db::commit();
            $this->success('审核成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('审核失败：' . $e->getMessage());
        }
    }

    /**
     * 获取报工详情
     */
    public function getReportDetail()
    {
        $report_id = $this->request->get('report_id');
        
        // 调试信息
        \think\Log::info('getReportDetail - report_id: ' . $report_id);
        
        if (!$report_id) {
            $this->error('参数错误');
        }
        
        $report = Report::with([
            'allocation' => function($query) {
                $query->with([
                    'order',
                    'model' => function($q) {
                        $q->with('product');
                    },
                    'process'
                ]);
            },
            'user'
        ])
            ->find($report_id);
            
        if (!$report) {
            $this->error('报工记录不存在');
        }
        
        // 如果allocation关联数据为空，尝试直接获取
        if (empty($report['allocation']['order']['order_no']) || empty($report['allocation']['model']['name'])) {
            $allocation = \app\admin\model\scanwork\Allocation::with(['order', 'model.product', 'process'])
                ->find($report['allocation_id']);
            if ($allocation) {
                $report['allocation'] = $allocation;
            }
        }
        
        // 调试信息
        \think\Log::info('Report data: ' . json_encode($report, JSON_UNESCAPED_UNICODE));
        
        // 获取报工图片
        $images = Db::name('scanwork_report_image')
            ->where('report_id', $report_id)
            ->select();
            
        // 为报工图片添加完整URL
        foreach ($images as &$image) {
            if (strpos($image['image_url'], 'http') !== 0) {
                $image['image_url'] = ConfigModel::getSiteDomain() . $image['image_url'];
            }
        }
            
        // 获取审核图片
        $auditImages = Db::name('scanwork_audit_image')
            ->alias('ai')
            ->join('fa_user u', 'u.id = ai.upload_user_id')
            ->where('ai.report_id', $report_id)
            ->field('ai.*, u.nickname as upload_user_name')
            ->select();
            
        // 为审核图片添加完整URL
        foreach ($auditImages as &$image) {
            if (strpos($image['image_url'], 'http') !== 0) {
                $image['image_url'] = ConfigModel::getSiteDomain() . $image['image_url'];
            }
        }
        
        // 获取审核视频
        $auditVideos = Db::name('scanwork_audit_video')
            ->alias('av')
            ->join('fa_user u', 'u.id = av.upload_user_id')
            ->where('av.report_id', $report_id)
            ->field('av.*, u.nickname as upload_user_name')
            ->select();
            
        // 为审核视频添加完整URL和格式化时间
        foreach ($auditVideos as &$video) {
            if (strpos($video['video_url'], 'http') !== 0) {
                $video['video_url'] = ConfigModel::getSiteDomain() . $video['video_url'];
            }
            $video['createtime_text'] = date('Y-m-d H:i:s', $video['createtime']);
        }
        
        // 获取产品编号图片（计件报工）
        $productItemImages = [];
        if ($report['allocation'] && $report['allocation']['work_type'] == 'piece') {
            // 获取报工的产品编号
            $itemNos = json_decode($report['item_nos'], true) ?: [];
            
            foreach ($itemNos as $itemNo) {
                // 获取该产品编号的报工图片
                $itemImages = Db::name('scanwork_item_report_image')
                    ->alias('iri')
                    ->join('fa_scanwork_product_item pi', 'pi.id = iri.item_id')
                    ->where('iri.report_id', $report_id)
                    ->where('pi.item_no', $itemNo)
                    ->field('iri.image_url')
                    ->select();
                
                // 为图片添加完整URL
                foreach ($itemImages as &$image) {
                    if (strpos($image['image_url'], 'http') !== 0) {
                        $image['image_url'] = ConfigModel::getSiteDomain() . $image['image_url'];
                    }
                }
                
                // 获取该产品编号的所有审核文件（图片和视频）
                $itemAuditFiles = Db::name('scanwork_item_audit_image')
                    ->alias('iai')
                    ->join('fa_scanwork_product_item pi', 'pi.id = iai.item_id')
                    ->join('fa_user u', 'u.id = iai.upload_user_id')
                    ->where('iai.report_id', $report_id)
                    ->where('pi.item_no', $itemNo)
                    ->field('iai.*, u.nickname as upload_user_name')
                    ->select();
                
                // 分离图片和视频
                $itemAuditImages = [];
                $itemAuditVideos = [];
                
                foreach ($itemAuditFiles as $file) {
                    // 为文件添加完整URL
                    if (strpos($file['image_url'], 'http') !== 0) {
                        $file['image_url'] = ConfigModel::getSiteDomain() . $file['image_url'];
                    }
                    
                    // 根据文件扩展名判断是图片还是视频
                    if (strpos($file['image_url'], '.mp4') !== false) {
                        // 这是视频文件
                        $file['createtime_text'] = date('Y-m-d H:i:s', $file['createtime']);
                        $file['video_url'] = $file['image_url'];
                        $file['thumb_url'] = ''; // 暂时为空
                        $itemAuditVideos[] = $file;
                    } else {
                        // 这是图片文件
                        $itemAuditImages[] = $file;
                    }
                }
                
                $productItemImages[] = [
                    'item_no' => $itemNo,
                    'images' => array_column($itemImages, 'image_url'),
                    'audit_images' => $itemAuditImages,
                    'audit_videos' => $itemAuditVideos,
                    'audit_status' => 0, // 默认待审核
                    'audit_reason' => ''
                ];
            }
        }
        
        $this->success('获取成功', [
            'report' => $report,
            'images' => $images,
            'audit_images' => $auditImages,
            'audit_videos' => $auditVideos,
            'productItemImages' => $productItemImages
        ]);
    }

    /**
     * 获取产品列表
     */
    public function getProducts()
    {
        $list = Product::where('status', 1)->select();
        $this->success('获取成功', $list);
    }

    /**
     * 获取产品型号列表
     */
    public function getModels()
    {
        $product_id = $this->request->get('product_id', '');
        $where = ['status' => 1];
        
        if ($product_id) {
            $where['product_id'] = $product_id;
        }
        
        $list = \app\admin\model\scanwork\ProductModel::with(['product'])
            ->where($where)
            ->select();
            
        $this->success('获取成功', $list);
    }

    /**
     * 获取订单型号
     */
    public function getOrderModels()
    {
        $order_id = $this->request->get('order_id');
        if (!$order_id) {
            $this->error('参数错误');
        }

        // 调试：检查订单是否存在
        $order = \app\admin\model\scanwork\Order::find($order_id);
        if (!$order) {
            $this->error('订单不存在');
        }

        // 调试：检查订单型号关联
        $orderModels = \app\admin\model\scanwork\OrderModel::with(['model.product'])
            ->where('order_id', $order_id)
            ->select();

        // 如果没有订单型号，返回空数组
        if (empty($orderModels)) {
            $this->success('获取成功', []);
        }

        // 获取所有工序
        $processes = \app\admin\model\scanwork\Process::where('status', 1)->select();

        $result = [];
        $batchCounter = []; // 用于统计每个型号的批次
        
        foreach ($orderModels as $index => $orderModel) {
            // 统计该型号的批次号
            $modelKey = $orderModel->model_id;
            if (!isset($batchCounter[$modelKey])) {
                $batchCounter[$modelKey] = 1;
            } else {
                $batchCounter[$modelKey]++;
            }
            $batchNumber = $batchCounter[$modelKey];
            
            foreach ($processes as $process) {
                // 检查该型号和工序是否有工价设置
                $processPrice = \app\admin\model\scanwork\ProcessPrice::where([
                    'model_id' => $orderModel->model_id,
                    'process_id' => $process->id
                ])->find();

                if ($processPrice) {
                    // 计算该工序已分配的数量
                    $allocatedQuantity = \app\admin\model\scanwork\Allocation::where([
                        'order_id' => $order_id,
                        'model_id' => $orderModel->model_id,
                        'process_id' => $process->id
                    ])->sum('quantity');
                    
                    // 计算该工序主动报工的数量
                    $activeReportQuantity = \app\admin\model\ActiveReport::where([
                        'order_id' => $order_id,
                        'model_id' => $orderModel->model_id,
                        'process_id' => $process->id
                    ])->sum('quantity');
                    
                    // 剩余可分配数量 = 订单型号数量 - 已分配数量 - 主动报工数量
                    $remainingQuantity = $orderModel->quantity - $allocatedQuantity - $activeReportQuantity;
                    
                    // 构建显示名称，包含批次信息
                    $displayName = $orderModel->model->product->name . ' - ' . $orderModel->model->name;
                    if ($batchNumber > 1) {
                        $displayName .= ' (第' . $batchNumber . '批)';
                    }
                    $displayName .= ' (' . $process->name . ')';
                    
                    $result[] = [
                        'id' => $orderModel->id,
                        'order_id' => $order_id,
                        'model_id' => $orderModel->model_id,
                        'model' => $orderModel->model,
                        'process_id' => $process->id,
                        'process' => $process,
                        'order_quantity' => $orderModel->quantity,
                        'allocated_quantity' => $allocatedQuantity,
                        'active_report_quantity' => $activeReportQuantity,
                        'remaining_quantity' => max(0, $remainingQuantity),
                        'order_total_quantity' => $order->total_quantity,
                        'display_name' => $displayName,
                        'batch_number' => $batchNumber,
                        'order_model_id' => $orderModel->id // 添加订单型号ID，用于区分批次
                    ];
                }
            }
        }

        $this->success('获取成功', $result);
    }

    /**
     * 获取工序列表
     */
    public function getProcesses()
    {
        $list = Process::where('status', 1)->select();
        $this->success('获取成功', $list);
    }

    /**
     * 获取员工列表
     */
    public function getUsers()
    {
        $list = User::where('status', 'normal')->field('id,nickname,avatar')->select();
        $this->success('获取成功', $list);
    }

    /**
     * 后端管理员登录
     */
    public function adminLogin()
    {
        $username = $this->request->post('username');
        $password = $this->request->post('password');
        
        \think\Log::info('管理员登录请求：' . json_encode(['username' => $username, 'password' => $password ? '***' : '']));
        
        if (!$username || !$password) {
            \think\Log::warning('登录参数不完整');
            $this->error('请输入用户名和密码');
        }
        
        try {
            // 验证管理员账号
            $admin = \app\admin\model\Admin::where('username', $username)->find();
            \think\Log::info('查询管理员结果：' . ($admin ? '找到管理员' : '未找到管理员'));
                
            if (!$admin) {
                \think\Log::warning('管理员不存在：' . $username);
                $this->error('用户名或密码错误');
            }
            
            // 验证密码（FastAdmin使用md5加密）
            $encryptedPassword = md5(md5($password) . $admin->salt);
            \think\Log::info('密码验证：' . ($encryptedPassword === $admin->password ? '密码正确' : '密码错误'));
            
            if ($encryptedPassword !== $admin->password) {
                \think\Log::warning('密码错误：' . $username);
                $this->error('用户名或密码错误');
            }
            
            // 检查管理员状态（支持多种状态表示方式）
            \think\Log::info('管理员状态检查：当前状态=' . $admin->status . ', 类型=' . gettype($admin->status));
            
            // 支持多种正常状态表示方式：1, '1', 'normal', 'active'
            $isNormal = ($admin->status == 1 || $admin->status === '1' || 
                        $admin->status === 'normal' || $admin->status === 'active');
            
            if (!$isNormal) {
                \think\Log::warning('管理员状态异常：' . $admin->status);
                $this->error('该账号已被禁用，当前状态：' . $admin->status);
            }
            
            $adminInfo = [
                'id' => $admin->id,
                'username' => $admin->username,
                'nickname' => $admin->nickname ?: $admin->username,
                'avatar' => $admin->avatar ?: '',
                'is_admin' => true
            ];
            
            // 生成token
            $token = md5($admin->id . time() . rand(1000, 9999));
            
            // 保存token到数据库
            $admin->token = $token;
            $admin->save();
            
            \think\Log::info('Token已保存到数据库: ' . $token);
            
            // 保存token到session
            session('admin_token', $token);
            session('admin_info', $adminInfo);
            
            \think\Log::info('登录成功，准备返回数据');
            
            // 获取管理员权限信息
            $permissions = $this->getAdminPermissionsInfo($admin->id);
            
            // 直接返回JSON数据，避免使用success方法
            return json([
                'code' => 1,
                'msg' => '登录成功',
                'data' => [
                    'token' => $token,
                    'admin_info' => $adminInfo,
                    'permissions' => $permissions
                ],
                'time' => time()
            ]);
            
        } catch (\Exception $e) {
            \think\Log::error('管理员登录失败：' . $e->getMessage() . ' 文件：' . $e->getFile() . ' 行号：' . $e->getLine() . ' 堆栈：' . $e->getTraceAsString());
            $this->error('登录失败：' . $e->getMessage());
        }
    }

    /**
     * 验证token
     */
    public function checkToken()
    {
        $token = $this->request->header('Authorization');
        if (!$token) {
            $this->error('未提供token');
        }
        
        // 处理Bearer token格式
        if (strpos($token, 'Bearer ') === 0) {
            $token = substr($token, 7);
        }
        
        // 验证session中的token
        $sessionToken = session('admin_token');
        if ($token !== $sessionToken) {
            $this->error('token无效');
        }
        
        $this->success('token有效');
    }

    /**
     * 创建分工任务
     */
    public function createAllocation()
    {
        
        $orderId = $this->request->post('order_id');
        $modelId = $this->request->post('model_id');
        $processId = $this->request->post('process_id');
        $userId = $this->request->post('user_id');
        $quantity = $this->request->post('quantity');
        $workType = $this->request->post('work_type', 'piece');
        $planId = $this->request->post('plan_id'); // 添加plan_id参数
        
        if (!$orderId || !$modelId || !$processId || !$userId || !$quantity) {
            $this->error('参数不完整');
        }
        
        Db::startTrans();
        try {
            // 检查是否传递的是订单型号ID还是产品型号ID
            $actualModelId = $modelId;
            $orderModel = null;
            
            // 首先尝试作为订单型号ID查找
            $orderModel = \app\admin\model\scanwork\OrderModel::where([
                'id' => $modelId,
                'order_id' => $orderId
            ])->find();
            
            if ($orderModel) {
                // 如果是订单型号ID，获取实际的产品型号ID
                $actualModelId = $orderModel->model_id;
            } else {
                // 如果不是订单型号ID，验证该产品型号是否属于该订单
                $orderModel = \app\admin\model\scanwork\OrderModel::where([
                    'order_id' => $orderId,
                    'model_id' => $modelId
                ])->find();
                
                if (!$orderModel) {
                    $this->error('所选型号不属于该订单');
                }
            }
            
            // 获取工序价格
            $processPrice = \app\admin\model\scanwork\ProcessPrice::where([
                'model_id' => $actualModelId,
                'process_id' => $processId
            ])->find();
            
            if (!$processPrice) {
                $this->error('该工序未设置价格');
            }
            
            // 计算工资
            $wage = 0;
            if ($workType == 'piece') {
                $wage = $quantity * ($processPrice->piece_price ?? 10); // 默认10元/件
            } else {
                $wage = $quantity * ($processPrice->time_price ?? 20); // 默认20元/小时
            }
            
            // 生成产品编号前缀
            $itemPrefix = '';
            if ($workType == 'piece' && $quantity > 0) {
                $order = \app\admin\model\scanwork\Order::find($orderId);
                $model = \app\admin\model\scanwork\ProductModel::find($actualModelId);
                $process = \app\admin\model\scanwork\Process::find($processId);
                
                if ($order && $model && $process) {
                    $itemPrefix = $order->order_no . '-' . $model->name . '-' . $process->name . '-';
                }
            }
            
            $data = [
                'order_id' => $orderId,
                'model_id' => $actualModelId,
                'process_id' => $processId,
                'user_id' => $userId,
                'quantity' => $quantity,
                'work_type' => $workType,
                'item_prefix' => $itemPrefix,
                'status' => 0, // 待完成
                'createtime' => time(),
                'updatetime' => time()
            ];
            
            // 如果提供了plan_id，则设置plan_id字段
            if ($planId) {
                $data['plan_id'] = $planId;
            }
            
            $allocation = \app\admin\model\scanwork\Allocation::create($data);
            $allocationId = $allocation->id;
            
            // 生成产品编号（仅计件工作）
            if ($workType == 'piece' && $quantity > 0 && $itemPrefix) {
                $itemNos = \app\admin\model\scanwork\ProductItem::generateItemNos($allocationId, $itemPrefix, $quantity);
                $createResult = \app\admin\model\scanwork\ProductItem::createItems($allocationId, $itemNos);
                if (!$createResult) {
                    throw new Exception('产品编号生成失败');
                }
            }
            
            // 更新订单状态
            $order = \app\admin\model\scanwork\Order::find($orderId);
            if ($order) {
                $order->updateStatus();
            }
            
            // 发送消息提醒给员工
            $this->sendAllocationNotification($allocationId, $userId, $orderId, $actualModelId, $processId, $quantity, $workType);
            
            Db::commit();
            $this->success('分工任务创建成功', $allocation);
            
        } catch (Exception $e) {
            Db::rollback();
            $this->error('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 批量创建分工任务
     */
    public function batchCreateAllocation()
    {
        
        $allocations = $this->request->post('allocations');
        
        if (!$allocations || !is_array($allocations)) {
            $this->error('参数错误');
        }
        
        Db::startTrans();
        try {
            $successCount = 0;
            $failCount = 0;
            
            foreach ($allocations as $item) {
                $orderId = $item['order_id'];
                $modelId = $item['model_id'];
                $processId = $item['process_id'];
                $userId = $item['user_id'];
                $quantity = $item['quantity'];
                $workType = $item['work_type'] ?? 'piece';
                
                // 获取工序价格
                $processPrice = \app\admin\model\scanwork\ProcessPrice::where([
                    'model_id' => $modelId,
                    'process_id' => $processId
                ])->find();
                
                if (!$processPrice) {
                    $failCount++;
                    continue;
                }
                
                // 计算工资
                $wage = 0;
                if ($workType == 'piece') {
                    $wage = $quantity * $processPrice->piece_price;
                } else {
                    $wage = $quantity * $processPrice->time_price;
                }
                
                // 生成产品编号前缀
                $itemPrefix = '';
                if ($workType == 'piece' && $quantity > 0) {
                    $order = \app\admin\model\scanwork\Order::find($orderId);
                    $model = \app\admin\model\scanwork\ProductModel::find($modelId);
                    $process = \app\admin\model\scanwork\Process::find($processId);
                    
                    if ($order && $model && $process) {
                        $itemPrefix = $order->order_no . '-' . $model->name . '-' . $process->name . '-';
                    }
                }
                
                $data = [
                    'order_id' => $orderId,
                    'model_id' => $modelId,
                    'process_id' => $processId,
                    'user_id' => $userId,
                    'quantity' => $quantity,
                    'work_type' => $workType,
                    'item_prefix' => $itemPrefix,
                    'piece_price' => $processPrice->piece_price,
                    'time_price' => $processPrice->time_price,
                    'wage' => $wage,
                    'status' => 0,
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                $allocation = \app\admin\model\scanwork\Allocation::create($data);
                $allocationId = $allocation->id;
                
                // 生成产品编号（仅计件工作）
                if ($workType == 'piece' && $quantity > 0 && $itemPrefix) {
                    $itemNos = \app\admin\model\scanwork\ProductItem::generateItemNos($allocationId, $itemPrefix, $quantity);
                    $createResult = \app\admin\model\scanwork\ProductItem::createItems($allocationId, $itemNos);
                    if (!$createResult) {
                        $failCount++;
                        continue;
                    }
                }
                
                $successCount++;
            }
            
            // 更新订单状态
            $orderIds = array_unique(array_column($allocations, 'order_id'));
            foreach ($orderIds as $orderId) {
                $order = \app\admin\model\scanwork\Order::find($orderId);
                if ($order) {
                    $order->updateStatus();
                }
            }
            
            Db::commit();
            $this->success("批量创建完成：成功 {$successCount} 条，失败 {$failCount} 条");
            
        } catch (Exception $e) {
            Db::rollback();
            $this->error('批量创建失败：' . $e->getMessage());
        }
    }

    /**
     * 调试：检查订单信息
     */
    public function debugOrder()
    {
        $order_id = $this->request->get('order_id');
        if (!$order_id) {
            $this->error('参数错误');
        }

        // 检查订单
        $order = \app\admin\model\scanwork\Order::find($order_id);
        if (!$order) {
            $this->error('订单不存在');
        }

        // 检查订单型号
        $orderModels = \app\admin\model\scanwork\OrderModel::with(['model.product'])
            ->where('order_id', $order_id)
            ->select();

        // 检查工序
        $processes = \app\admin\model\scanwork\Process::where('status', 1)->select();

        // 检查工价设置
        $processPrices = \app\admin\model\scanwork\ProcessPrice::select();

        $debug = [
            'order' => $order,
            'order_models_count' => count($orderModels),
            'order_models' => $orderModels,
            'processes_count' => count($processes),
            'processes' => $processes,
            'process_prices_count' => count($processPrices),
            'process_prices' => $processPrices
        ];

        $this->success('调试信息', $debug);
    }

    /**
     * 获取主动报工详情
     */
    public function getActiveReportDetail()
    {
        $report_id = $this->request->get('report_id');
        
        if (!$report_id) {
            $this->error('参数错误');
        }
        
        // 调试信息
        \think\Log::info('getActiveReportDetail - report_id: ' . $report_id);
        
        // 先检查记录是否存在
        $exists = \think\Db::name('scanwork_active_report')->where('id', $report_id)->find();
        if (!$exists) {
            \think\Log::error('主动报工记录不存在 - report_id: ' . $report_id);
            $this->error('报工记录不存在');
        }
        
        \think\Log::info('主动报工记录存在: ' . json_encode($exists, JSON_UNESCAPED_UNICODE));
        
        // 获取主动报工记录
        $activeReport = \think\Db::name('scanwork_active_report')
            ->alias('ar')
            ->join('scanwork_order o', 'ar.order_id = o.id')
            ->join('scanwork_model m', 'ar.model_id = m.id')
            ->join('scanwork_product p', 'm.product_id = p.id')
            ->join('scanwork_process pr', 'ar.process_id = pr.id')
            ->join('user u', 'ar.user_id = u.id')
            ->field('ar.*, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name, u.nickname as user_name')
            ->where('ar.id', $report_id)
            ->find();
            
        if (!$activeReport) {
            \think\Log::error('主动报工记录关联查询失败 - report_id: ' . $report_id);
            $this->error('报工记录不存在');
        }
        
        \think\Log::info('主动报工记录关联查询成功: ' . json_encode($activeReport, JSON_UNESCAPED_UNICODE));
        
        // 格式化时间
        $activeReport['createtime_text'] = date('Y-m-d H:i:s', $activeReport['createtime']);
        $activeReport['status_text'] = $this->getStatusText($activeReport['status']);
        
        // 获取产品编号和图片（按编号分组）
        $productItemImages = \think\Db::name('scanwork_active_report_product_item')
            ->where('active_report_id', $report_id)
            ->field('item_no, image_url')
            ->select();
            
        \think\Log::info('产品编号图片数量: ' . count($productItemImages));
            
        // 按产品编号分组图片
        $groupedProductImages = [];
        foreach ($productItemImages as $item) {
            $itemNo = $item['item_no'];
            if (!isset($groupedProductImages[$itemNo])) {
                $groupedProductImages[$itemNo] = [
                    'item_no' => $itemNo,
                    'images' => [],
                    'audit_images' => [],
                    'audit_videos' => [],
                    'audit_status' => 0, // 0: 待审核, 1: 通过, 2: 拒绝
                    'audit_reason' => ''
                ];
            }
            $groupedProductImages[$itemNo]['images'][] = $item['image_url'];
        }
        
        // 获取该主动报工的所有审核文件（图片和视频）
        $auditFiles = \think\Db::name('scanwork_active_report_image')
            ->where('active_report_id', $report_id)
            ->where('image_type', 2) // 管理员上传的审核文件
            ->field('*')
            ->select();
            
        // 获取该主动报工的所有审核视频
        $auditVideos = \think\Db::name('scanwork_active_report_video')
            ->where('active_report_id', $report_id)
            ->where('video_type', 2) // 管理员上传的审核视频
            ->field('*')
            ->select();
            
        \think\Log::info('审核文件数量: ' . count($auditFiles) . ', 审核视频数量: ' . count($auditVideos));
        
        // 分离图片和视频，并按产品编号分组
        foreach ($auditFiles as $file) {
            // 为文件添加完整URL
            if (strpos($file['image_url'], 'http') !== 0) {
                $file['image_url'] = request()->domain() . $file['image_url'];
            }
            
            // 根据文件扩展名判断是图片还是视频
            if (strpos($file['image_url'], '.mp4') !== false) {
                // 这是视频文件
                $file['createtime_text'] = date('Y-m-d H:i:s', $file['createtime']);
                $file['video_url'] = $file['image_url'];
                $file['thumb_url'] = ''; // 暂时为空
                
                // 添加到对应的产品编号组（如果有item_no字段的话）
                if (isset($file['item_no']) && isset($groupedProductImages[$file['item_no']])) {
                    $groupedProductImages[$file['item_no']]['audit_videos'][] = $file;
                } else {
                    // 如果没有item_no，添加到所有组
                    foreach ($groupedProductImages as &$group) {
                        $group['audit_videos'][] = $file;
                    }
                }
            } else {
                // 这是图片文件
                // 添加到对应的产品编号组（如果有item_no字段的话）
                if (isset($file['item_no']) && isset($groupedProductImages[$file['item_no']])) {
                    $groupedProductImages[$file['item_no']]['audit_images'][] = $file;
                } else {
                    // 如果没有item_no，添加到所有组
                    foreach ($groupedProductImages as &$group) {
                        $group['audit_images'][] = $file;
                    }
                }
            }
        }
        
        // 处理审核视频（从video表获取）
        foreach ($auditVideos as $video) {
            // 为视频添加完整URL
            if (strpos($video['video_url'], 'http') !== 0) {
                $video['video_url'] = ConfigModel::getSiteDomain() . $video['video_url'];
            }
            
            $video['createtime_text'] = date('Y-m-d H:i:s', $video['createtime']);
            $video['thumb_url'] = ''; // 暂时为空
            
            // 添加到对应的产品编号组（如果有item_no字段的话）
            if (isset($video['item_no']) && isset($groupedProductImages[$video['item_no']])) {
                $groupedProductImages[$video['item_no']]['audit_videos'][] = $video;
            } else {
                // 如果没有item_no，添加到所有组
                foreach ($groupedProductImages as &$group) {
                    $group['audit_videos'][] = $video;
                }
            }
        }
        
        // 获取通用图片（计时图片）
        $generalImages = \think\Db::name('scanwork_active_report_image')
            ->where('active_report_id', $report_id)
            ->where('image_type', 1) // 员工上传的图片
            ->field('image_url')
            ->select();
            
        $generalImageUrls = array_column($generalImages, 'image_url');
        
        $this->success('获取成功', [
            'activeReport' => $activeReport,
            'productItemImages' => array_values($groupedProductImages),
            'generalImages' => $generalImageUrls,
            'auditImages' => [], // 保持兼容性
            'audit_videos' => [] // 保持兼容性
        ]);
    }

    /**
     * 审核主动报工（按产品编号）
     */
    public function auditActiveReport()
    {
        try {
            // 获取基本参数
            $report_id = input('post.report_id');
            $status = input('post.status', 1);
            $audit_reason = input('post.audit_reason', '');
            
            \think\Log::info('auditActiveReport - 基本参数: report_id=' . $report_id . ', status=' . $status . ', audit_reason=' . $audit_reason);
            
            if (!$report_id) {
                $this->error('参数错误');
            }
            
            // 检查报工记录是否存在
            $activeReport = Db::name('scanwork_active_report')->where('id', $report_id)->find();
            if (!$activeReport) {
                $this->error('报工记录不存在');
            }
            
            // 开始事务
            Db::startTrans();
            
            // 更新主动报工记录状态
            $updateResult = Db::name('scanwork_active_report')
                ->where('id', $report_id)
                ->update([
                    'status' => $status,
                    'audit_reason' => $audit_reason,
                    'audit_time' => time(),
                    'updatetime' => time()
                ]);
            
            \think\Log::info('auditActiveReport - 状态更新结果: ' . $updateResult);
            
            // 处理审核图片（如果有的话）- 支持多种数据格式
            try {
                \think\Log::info('auditActiveReport - 开始处理审核图片');
                \think\Log::info('auditActiveReport - $_POST内容: ' . json_encode($_POST, JSON_UNESCAPED_UNICODE));
                
                // 尝试从多种来源获取audit_images
                $audit_images = null;
                
                // 1. 尝试从原始输入获取JSON数据（优先）
                $raw_input = file_get_contents('php://input');
                \think\Log::info('auditActiveReport - 原始输入: ' . $raw_input);
                
                if (!empty($raw_input)) {
                    $json_data = json_decode($raw_input, true);
                    \think\Log::info('auditActiveReport - JSON解析结果: ' . json_encode($json_data, JSON_UNESCAPED_UNICODE));
                    
                    if (isset($json_data['audit_images'])) {
                        $audit_images_raw = $json_data['audit_images'];
                        \think\Log::info('auditActiveReport - 从JSON获取audit_images: ' . var_export($audit_images_raw, true));
                    }
                }
                // 2. 尝试从$_POST获取
                elseif (isset($_POST['audit_images'])) {
                    $audit_images_raw = $_POST['audit_images'];
                    \think\Log::info('auditActiveReport - 从$_POST获取audit_images: ' . var_export($audit_images_raw, true));
                }
                // 3. 尝试从input()获取
                elseif (input('post.audit_images')) {
                    $audit_images_raw = input('post.audit_images');
                    \think\Log::info('auditActiveReport - 从input()获取audit_images: ' . var_export($audit_images_raw, true));
                }
                
                if (isset($audit_images_raw) && !empty($audit_images_raw)) {
                    // 如果已经是数组，直接使用
                    if (is_array($audit_images_raw)) {
                        $audit_images = $audit_images_raw;
                        \think\Log::info('auditActiveReport - audit_images 已经是数组');
                    } 
                    // 如果是字符串，尝试解析JSON
                    elseif (is_string($audit_images_raw)) {
                        $audit_images = json_decode($audit_images_raw, true);
                        \think\Log::info('auditActiveReport - JSON解码后: ' . json_encode($audit_images, JSON_UNESCAPED_UNICODE));
                    } 
                    // 其他情况，跳过
                    else {
                        \think\Log::info('auditActiveReport - audit_images 格式不支持，跳过');
                        $audit_images = null;
                    }
                    
                    if (is_array($audit_images)) {
                        \think\Log::info('auditActiveReport - 处理审核图片数组，数量: ' . count($audit_images));
                        foreach ($audit_images as $imageUrl) {
                            if (is_string($imageUrl)) {
                                \think\Log::info('auditActiveReport - 处理图片: ' . $imageUrl);
                                
                                // 检查图片是否已经存在
                                $exists = Db::name('scanwork_active_report_image')
                                    ->where('active_report_id', $report_id)
                                    ->where('image_url', $imageUrl)
                                    ->where('image_type', 2)
                                    ->find();
                                
                                if (!$exists) {
                                    $insertResult = Db::name('scanwork_active_report_image')->insert([
                                        'active_report_id' => $report_id,
                                        'image_url' => $imageUrl,
                                        'image_type' => 2,
                                        'createtime' => time()
                                    ]);
                                    \think\Log::info('auditActiveReport - 图片保存成功，结果: ' . $insertResult);
                                } else {
                                    \think\Log::info('auditActiveReport - 图片已存在，跳过');
                                }
                            }
                        }
                    }
                } else {
                    \think\Log::info('auditActiveReport - 没有找到audit_images数据');
                }
            } catch (Exception $e) {
                \think\Log::error('auditActiveReport - 处理审核图片时出错: ' . $e->getMessage());
                // 图片处理出错不影响整体审核流程
            }
            
            // 如果审核通过，创建溯源码
            if ($status == 1) {
                $this->createTraceCodeAfterActiveAudit($activeReport);
            }
            
            // 提交事务
            Db::commit();
            \think\Log::info('auditActiveReport - 审核成功');
            $this->success('审核成功');
            
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            \think\Log::error('auditActiveReport - 审核失败: ' . $e->getMessage());
            $this->error('审核失败：' . $e->getMessage());
        }
    }

    /**
     * 发送分工通知消息
     */
    private function sendAllocationNotification($allocationId, $userId, $orderId, $modelId, $processId, $quantity, $workType)
    {
        try {
            // 获取相关信息
            $order = \app\admin\model\scanwork\Order::find($orderId);
            $model = \app\admin\model\scanwork\ProductModel::with('product')->find($modelId);
            $process = \app\admin\model\scanwork\Process::find($processId);
            
            if (!$order || !$model || !$process) {
                \think\Log::error('发送分工通知失败：相关数据不存在');
                return false;
            }
            
            // 构建分工数据
            $allocationData = [
                'order_no' => $order->order_no,
                'product_name' => $model->product->name,
                'model_name' => $model->name,
                'process_name' => $process->name,
                'quantity' => $quantity,
                'work_type_text' => $workType == 'piece' ? '计件' : '计时'
            ];
            
            // 使用MessageService发送消息
            $messageService = new \app\common\library\MessageService();
            $result = $messageService->sendAllocationMessage($userId, $allocationData);
            
            \think\Log::info("分工通知发送成功 - 用户ID: {$userId}, 结果: " . json_encode($result));
            return $result;
            
        } catch (Exception $e) {
            \think\Log::error('发送分工通知失败：' . $e->getMessage());
            return false;
        }
    }

    /**
     * 发送微信模板消息
     */
    private function sendWechatTemplateMessage($user, $title, $content, $allocationId)
    {
        try {
            // 检查用户是否有微信openid
            if (empty($user->openid)) {
                \think\Log::info('用户没有绑定微信openid，跳过模板消息发送');
                return false;
            }
            
            // 获取分工详细信息
            $allocation = \app\admin\model\scanwork\Allocation::with(['order', 'model.product', 'process'])->find($allocationId);
            if (!$allocation) {
                \think\Log::error('分工信息不存在，无法发送模板消息');
                return false;
            }
            
            // 构建模板消息数据
            $allocationData = [
                'order_no' => $allocation->order->order_no,
                'product_name' => $allocation->model->product->name,
                'model_name' => $allocation->model->name,
                'process_name' => $allocation->process->name,
                'quantity' => $allocation->quantity,
                'work_type_text' => $allocation->work_type == 'piece' ? '计件' : '计时'
            ];
            
            // 使用微信消息推送工具类
            $wechatMessage = new \app\common\library\WechatMessage();
            $result = $wechatMessage->sendAllocationNotification($user->openid, $allocationData);
            
            \think\Log::info('微信模板消息发送成功 - 用户: ' . $user->nickname);
            return $result;
            
        } catch (Exception $e) {
            \think\Log::error('微信模板消息发送失败：' . $e->getMessage());
            return false;
        }
    }

    /**
     * 发送小程序订阅消息
     */
    private function sendMiniProgramSubscribeMessage($user, $allocationId)
    {
        try {
            // 检查是否启用小程序订阅消息推送
            if (!config('wechat.message.enable_miniprogram_push')) {
                \think\Log::info('小程序订阅消息推送已禁用');
                return false;
            }
            
            // 检查用户是否有微信openid
            if (empty($user->openid)) {
                \think\Log::info('用户没有绑定微信openid，跳过小程序订阅消息发送');
                return false;
            }
            
            // 获取分工详细信息
            $allocation = \app\admin\model\scanwork\Allocation::with(['order', 'model.product', 'process'])->find($allocationId);
            if (!$allocation) {
                \think\Log::error('分工信息不存在，无法发送小程序订阅消息');
                return false;
            }
            
            // 构建订阅消息数据
            $allocationData = [
                'order_no' => $allocation->order->order_no,
                'product_name' => $allocation->model->product->name,
                'model_name' => $allocation->model->name,
                'process_name' => $allocation->process->name,
                'quantity' => $allocation->quantity,
                'work_type_text' => $allocation->work_type == 'piece' ? '计件' : '计时'
            ];
            
            // 使用小程序订阅消息推送工具类
            $miniProgramMessage = new \app\common\library\MiniProgramMessage();
            $result = $miniProgramMessage->sendAllocationNotification($user->openid, $allocationData);
            
            \think\Log::info('小程序订阅消息发送成功 - 用户: ' . $user->nickname);
            return $result;
            
        } catch (Exception $e) {
            \think\Log::error('小程序订阅消息发送失败：' . $e->getMessage());
            return false;
        }
    }

    /**
     * 获取状态文本
     */
    private function getStatusText($status)
    {
        switch ($status) {
            case 0:
                return '待审核';
            case 1:
                return '已通过';
            case 2:
                return '已拒绝';
            default:
                return '未知';
        }
    }

    /**
     * 上传到七牛云存储
     */
    protected function uploadToQiniuSimple($localPath, $filename)
    {
        $maxRetries = 3; // 最大重试次数
        $retryDelay = 1; // 重试间隔（秒）
        
        for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
            try {
                \think\Log::info("uploadToQiniuSimple - 第{$attempt}次尝试上传到七牛云，本地路径: " . $localPath);
                
                // 从数据库获取七牛云配置
                $qiniuConfig = Db::name('yuncunchu_config')->where('type', 'qiniu')->where('status', 1)->find();
                if (!$qiniuConfig) {
                    \think\Log::error('uploadToQiniuSimple - 未找到七牛云配置');
                    return null;
                }
                
                $configData = json_decode($qiniuConfig['config'], true);
                if (!$configData) {
                    \think\Log::error('uploadToQiniuSimple - 七牛云配置解析失败');
                    return null;
                }
                
                \think\Log::info('uploadToQiniuSimple - 使用数据库配置: ' . json_encode($configData));
                
                // 生成云存储路径（保持与本地路径一致）
                $cloudPath = 'uploads/audit/' . $filename;
                
                // 生成上传token
                $accessKey = $configData['access_key'];
                $secretKey = $configData['secret_key'];
                $bucket = $configData['bucket'];
                $key = $cloudPath;
                
                // 生成上传策略
                $policy = [
                    'scope' => $bucket,
                    'deadline' => time() + 3600, // 1小时过期
                    'returnBody' => '{"key":"$(key)","hash":"$(etag)","size":"$(fsize)","mimeType":"$(mimeType)"}'
                ];
                
                $policyJson = json_encode($policy);
                $policyBase64 = base64_encode($policyJson);
                $sign = hash_hmac('sha1', $policyBase64, $secretKey, true);
                $token = $accessKey . ':' . base64_encode($sign) . ':' . $policyBase64;
                
                // 准备上传数据
                $postData = [
                    'token' => $token,
                    'key' => $key,
                    'file' => new \CURLFile($localPath)
                ];
                
                // 上传到七牛云
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, 'https://up-z2.qiniup.com/');
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_TIMEOUT, 30);
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时
                
                $response = curl_exec($ch);
                $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                $error = curl_error($ch);
                curl_close($ch);
                
                \think\Log::info("uploadToQiniuSimple - 第{$attempt}次尝试 - 七牛云响应: " . $response);
                \think\Log::info("uploadToQiniuSimple - 第{$attempt}次尝试 - HTTP状态码: " . $httpCode);
                if ($error) {
                    \think\Log::error("uploadToQiniuSimple - 第{$attempt}次尝试 - CURL错误: " . $error);
                }
                
                // 添加更详细的调试信息
                \think\Log::info("uploadToQiniuSimple - 第{$attempt}次尝试 - 上传参数: " . json_encode([
                    'localPath' => $localPath,
                    'filename' => $filename,
                    'cloudPath' => $cloudPath,
                    'bucket' => $bucket,
                    'domain' => $configData['domain']
                ]));
                
                if ($httpCode == 200) {
                    $result = json_decode($response, true);
                    if ($result && isset($result['key'])) {
                        $url = $configData['domain'] . '/' . $result['key'];
                        \think\Log::info("uploadToQiniuSimple - 第{$attempt}次尝试成功，URL: " . $url);
                        return $url;
                    }
                }
                
                // 如果不是最后一次尝试，等待后重试
                if ($attempt < $maxRetries) {
                    \think\Log::info("uploadToQiniuSimple - 第{$attempt}次尝试失败，等待{$retryDelay}秒后重试...");
                    sleep($retryDelay);
                    $retryDelay *= 2; // 指数退避
                }
                
            } catch (Exception $e) {
                \think\Log::error("uploadToQiniuSimple - 第{$attempt}次尝试异常: " . $e->getMessage());
                if ($attempt < $maxRetries) {
                    sleep($retryDelay);
                    $retryDelay *= 2;
                }
            }
        }
        
        \think\Log::error('uploadToQiniuSimple - 所有尝试都失败了');
        return null;
    }

    /**
     * 上传到阿里云OSS
     */
    protected function uploadToAliyunOSS($localPath, $cloudPath, $configData)
    {
        try {
            \think\Log::info('uploadToAliyunOSS - 开始上传到阿里云OSS');
            
            // 检查阿里云OSS配置
            if (empty($configData['access_key_id']) || empty($configData['access_key_secret']) || 
                empty($configData['bucket']) || empty($configData['endpoint'])) {
                \think\Log::error('uploadToAliyunOSS - 阿里云OSS配置不完整');
                return null;
            }
            
            // 读取文件内容
            $content = file_get_contents($localPath);
            if ($content === false) {
                \think\Log::error('uploadToAliyunOSS - 无法读取文件内容');
                return null;
            }
            
            // 使用阿里云OSS SDK上传
            $ossClient = new \OSS\OssClient(
                $configData['access_key_id'],
                $configData['access_key_secret'],
                $configData['endpoint']
            );
            
            // 上传文件到OSS
            $result = $ossClient->putObject($configData['bucket'], $cloudPath, $content);
            
            // 生成文件URL
            if (isset($configData['domain']) && !empty($configData['domain'])) {
                $fileUrl = rtrim($configData['domain'], '/') . '/' . $cloudPath;
            } else {
                $fileUrl = $result['info']['url'];
            }
            
            \think\Log::info('uploadToAliyunOSS - 上传成功，URL: ' . $fileUrl);
            return $fileUrl;
            
        } catch (Exception $e) {
            \think\Log::error('uploadToAliyunOSS - 异常: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * 上传到腾讯云COS
     */
    protected function uploadToTencentCOS($localPath, $cloudPath, $configData)
    {
        try {
            \think\Log::info('uploadToTencentCOS - 开始上传到腾讯云COS');
            
            // 检查腾讯云COS配置
            if (empty($configData['secret_id']) || empty($configData['secret_key']) || 
                empty($configData['bucket']) || empty($configData['region'])) {
                \think\Log::error('uploadToTencentCOS - 腾讯云COS配置不完整');
                return null;
            }
            
            // 读取文件内容
            $content = file_get_contents($localPath);
            if ($content === false) {
                \think\Log::error('uploadToTencentCOS - 无法读取文件内容');
                return null;
            }
            
            // 使用腾讯云COS SDK上传
            $cosClient = new \Qcloud\Cos\Client([
                'region' => $configData['region'],
                'credentials' => [
                    'secretId' => $configData['secret_id'],
                    'secretKey' => $configData['secret_key'],
                ]
            ]);
            
            // 上传文件到COS
            $result = $cosClient->putObject([
                'Bucket' => $configData['bucket'],
                'Key' => $cloudPath,
                'Body' => $content
            ]);
            
            // 生成文件URL
            if (isset($configData['domain']) && !empty($configData['domain'])) {
                $fileUrl = rtrim($configData['domain'], '/') . '/' . $cloudPath;
            } else {
                $fileUrl = $result['ObjectURL'];
            }
            
            \think\Log::info('uploadToTencentCOS - 上传成功，URL: ' . $fileUrl);
            return $fileUrl;
            
        } catch (Exception $e) {
            \think\Log::error('uploadToTencentCOS - 异常: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * 通用云存储上传方法（根据默认配置选择存储提供商）
     */
    protected function uploadToCloudStorage($localPath, $filename)
    {
        try {
            \think\Log::info('uploadToCloudStorage - 开始上传到云存储');
            
            // 获取默认云存储配置
            $defaultConfig = Db::name('yuncunchu_config')->where('is_default', 1)->where('status', 1)->find();
            if (!$defaultConfig) {
                \think\Log::error('uploadToCloudStorage - 未找到默认云存储配置');
                return null;
            }
            
            $configData = $defaultConfig['config'];
            if (is_string($configData)) {
                $configData = json_decode($configData, true);
            }
            
            // 生成云存储路径
            $cloudPath = 'uploads/audit/' . $filename;
            
            \think\Log::info('uploadToCloudStorage - 使用存储类型: ' . $defaultConfig['type']);
            
            // 根据存储类型选择上传方法
            switch ($defaultConfig['type']) {
                case 'qiniu':
                    return $this->uploadToQiniu($localPath, $cloudPath, $configData);
                case 'aliyun_oss':
                    return $this->uploadToAliyunOSS($localPath, $cloudPath, $configData);
                case 'tencent_cos':
                    return $this->uploadToTencentCOS($localPath, $cloudPath, $configData);
                case 'local':
                    // 本地存储不需要上传，直接返回本地URL
                    $uploadPath = $configData['path'] ?? '/uploads';
                    $uploadUrl = $configData['url'] ?? '/uploads';
                    $localUrl = $uploadUrl . '/audit/' . $filename;
                    return ConfigModel::getSiteDomain() . $localUrl;
                default:
                    \think\Log::error('uploadToCloudStorage - 不支持的存储类型: ' . $defaultConfig['type']);
                    return null;
            }
            
        } catch (Exception $e) {
            \think\Log::error('uploadToCloudStorage - 异常: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * 上传到七牛云（从uploadToQiniuSimple重构而来）
     */
    protected function uploadToQiniu($localPath, $cloudPath, $configData)
    {
        try {
            \think\Log::info('uploadToQiniu - 开始上传到七牛云');
            
            // 检查七牛云配置
            if (empty($configData['access_key']) || empty($configData['secret_key']) || 
                empty($configData['bucket']) || empty($configData['domain'])) {
                \think\Log::error('uploadToQiniu - 七牛云配置不完整');
                return null;
            }
            
            // 生成上传token
            $accessKey = $configData['access_key'];
            $secretKey = $configData['secret_key'];
            $bucket = $configData['bucket'];
            $key = $cloudPath;
            
            // 生成上传策略
            $policy = [
                'scope' => $bucket,
                'deadline' => time() + 3600, // 1小时过期
                'returnBody' => '{"key":"$(key)","hash":"$(etag)","size":"$(fsize)","mimeType":"$(mimeType)"}'
            ];
            
            $policyJson = json_encode($policy);
            $policyBase64 = base64_encode($policyJson);
            $sign = hash_hmac('sha1', $policyBase64, $secretKey, true);
            $token = $accessKey . ':' . base64_encode($sign) . ':' . $policyBase64;
            
            // 准备上传数据
            $postData = [
                'token' => $token,
                'key' => $key,
                'file' => new \CURLFile($localPath)
            ];
            
            // 上传到七牛云
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://up-z2.qiniup.com/');
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
            
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            \think\Log::info('uploadToQiniu - 七牛云响应: ' . $response);
            \think\Log::info('uploadToQiniu - HTTP状态码: ' . $httpCode);
            
            if ($httpCode == 200) {
                $result = json_decode($response, true);
                if ($result && isset($result['key'])) {
                    $url = $configData['domain'] . '/' . $result['key'];
                    \think\Log::info('uploadToQiniu - 上传成功，URL: ' . $url);
                    return $url;
                }
            }
            
            \think\Log::error('uploadToQiniu - 上传失败');
            return null;
            
        } catch (Exception $e) {
            \think\Log::error('uploadToQiniu - 异常: ' . $e->getMessage());
            return null;
        }
    }

    // ==================== 产品管理 ====================
    
    /**
     * 获取产品列表
     */
    public function getProductList()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $status = $this->request->get('status', '');
        
        $where = [];
        if ($status !== '') {
            $where['status'] = $status;
        }
        
        $list = Product::with(['models'])
            ->where($where)
            ->order('id', 'desc')
            ->paginate($limit, false, ['page' => $page]);
        
        $this->success('获取成功', [
            'list' => $list->items(),
            'total' => $list->total(),
            'page' => $page,
            'limit' => $limit
        ]);
    }

    /**
     * 创建产品
     */
    public function createProduct()
    {
        $data = $this->request->post();
        
        if (empty($data['name'])) {
            $this->error('产品名称不能为空');
        }
        
        Db::startTrans();
        try {
            $product = Product::create([
                'name' => $data['name'],
                'specification' => $data['description'] ?? '', // 使用specification字段存储描述
                'status' => $data['status'] ?? 1,
                'createtime' => time(),
                'updatetime' => time()
            ]);
            
            Db::commit();
            $this->success('创建成功', $product);
        } catch (Exception $e) {
            Db::rollback();
            $this->error('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 更新产品
     */
    public function updateProduct()
    {
        $productId = $this->request->post('id');
        $data = $this->request->post();
        
        if (!$productId || empty($data['name'])) {
            $this->error('参数错误');
        }
        
        $product = Product::find($productId);
        if (!$product) {
            $this->error('产品不存在');
        }
        
        Db::startTrans();
        try {
            $product->save([
                'name' => $data['name'],
                'specification' => $data['description'] ?? '', // 使用specification字段存储描述
                'status' => $data['status'] ?? 1,
                'updatetime' => time()
            ]);
            
            Db::commit();
            $this->success('更新成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('更新失败：' . $e->getMessage());
        }
    }

    /**
     * 删除产品
     */
    public function deleteProduct()
    {
        $productId = $this->request->post('id');
        if (!$productId) {
            $this->error('参数错误');
        }
        
        $product = Product::find($productId);
        if (!$product) {
            $this->error('产品不存在');
        }
        
        // 检查是否有关联的型号
        $modelCount = \app\admin\model\scanwork\ProductModel::where('product_id', $productId)->count();
        if ($modelCount > 0) {
            $this->error("产品【{$product->name}】下还有{$modelCount}个型号，请先删除相关型号");
        }
        
        Db::startTrans();
        try {
            $product->delete();
            Db::commit();
            $this->success('删除成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('删除失败：' . $e->getMessage());
        }
    }

    // ==================== 产品型号管理 ====================
    
    /**
     * 获取产品型号列表
     */
    public function getProductModelList()
    {
        $id = $this->request->get('id', '');
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $product_id = $this->request->get('product_id', '');
        $status = $this->request->get('status', '');
        
        // 如果传入了id，返回单个型号的详细信息
        if ($id) {
            $model = \app\admin\model\scanwork\ProductModel::with(['product'])
                ->where('id', $id)
                ->find();
            
            if (!$model) {
                $this->error('型号不存在');
            }
            
            $this->success('获取成功', [
                'list' => [$model],
                'total' => 1
            ]);
            return;
        }
        
        $where = [];
        if ($product_id) {
            $where['product_id'] = $product_id;
        }
        if ($status !== '') {
            $where['status'] = $status;
        }
        
        $list = \app\admin\model\scanwork\ProductModel::with(['product'])
            ->where($where)
            ->order('id', 'desc')
            ->paginate($limit, false, ['page' => $page]);
        
        $this->success('获取成功', [
            'list' => $list->items(),
            'total' => $list->total(),
            'page' => $page,
            'limit' => $limit
        ]);
    }

    /**
     * 创建产品型号
     */
    public function createProductModel()
    {
        $data = $this->request->post();
        
        if (empty($data['name']) || empty($data['product_id'])) {
            $this->error('型号名称和产品不能为空');
        }
        
        Db::startTrans();
        try {
            $model = \app\admin\model\scanwork\ProductModel::create([
                'product_id' => $data['product_id'],
                'name' => $data['name'],
                'model_code' => $data['model_code'] ?? '',
                'fabric_color' => $data['fabric_color'] ?? '',
                'description' => $data['description'] ?? '',
                'status' => $data['status'] ?? 1,
                'createtime' => time(),
                'updatetime' => time()
            ]);
            
            Db::commit();
            $this->success('创建成功', $model);
        } catch (Exception $e) {
            Db::rollback();
            $this->error('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 更新产品型号
     */
    public function updateProductModel()
    {
        $modelId = $this->request->post('id');
        $data = $this->request->post();
        
        if (!$modelId || empty($data['name']) || empty($data['product_id'])) {
            $this->error('参数错误');
        }
        
        $model = \app\admin\model\scanwork\ProductModel::find($modelId);
        if (!$model) {
            $this->error('型号不存在');
        }
        
        Db::startTrans();
        try {
            $model->save([
                'product_id' => $data['product_id'],
                'name' => $data['name'],
                'model_code' => $data['model_code'] ?? '',
                'fabric_color' => $data['fabric_color'] ?? '',
                'description' => $data['description'] ?? '',
                'status' => $data['status'] ?? 1,
                'updatetime' => time()
            ]);
            
            Db::commit();
            $this->success('更新成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('更新失败：' . $e->getMessage());
        }
    }

    /**
     * 删除产品型号
     */
    public function deleteProductModel()
    {
        $modelId = $this->request->post('id');
        if (!$modelId) {
            $this->error('参数错误');
        }
        
        $model = \app\admin\model\scanwork\ProductModel::find($modelId);
        if (!$model) {
            $this->error('型号不存在');
        }
        
        // 检查是否有关联的工序工价
        $priceCount = \app\admin\model\scanwork\ProcessPrice::where('model_id', $modelId)->count();
        if ($priceCount > 0) {
            $this->error("型号【{$model->name}】下还有{$priceCount}个工序工价设置，请先删除相关工价");
        }
        
        Db::startTrans();
        try {
            $model->delete();
            Db::commit();
            $this->success('删除成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('删除失败：' . $e->getMessage());
        }
    }

    // ==================== 工序管理 ====================
    
    /**
     * 获取工序列表
     */
    public function getProcessList()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $status = $this->request->get('status', '');
        
        $where = [];
        if ($status !== '') {
            $where['status'] = $status;
        }
        
        $list = Process::where($where)
            ->order('id', 'desc')
            ->paginate($limit, false, ['page' => $page]);
        
        $this->success('获取成功', [
            'list' => $list->items(),
            'total' => $list->total(),
            'page' => $page,
            'limit' => $limit
        ]);
    }

    /**
     * 创建工序
     */
    public function createProcess()
    {
        $data = $this->request->post();
        
        if (empty($data['name'])) {
            $this->error('工序名称不能为空');
        }
        
        Db::startTrans();
        try {
            $process = Process::create([
                'name' => $data['name'],
                'description' => $data['description'] ?? '',
                'status' => $data['status'] ?? 1,
                'createtime' => time(),
                'updatetime' => time()
            ]);
            
            Db::commit();
            $this->success('创建成功', $process);
        } catch (Exception $e) {
            Db::rollback();
            $this->error('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 更新工序
     */
    public function updateProcess()
    {
        $processId = $this->request->post('id');
        $data = $this->request->post();
        
        if (!$processId || empty($data['name'])) {
            $this->error('参数错误');
        }
        
        $process = Process::find($processId);
        if (!$process) {
            $this->error('工序不存在');
        }
        
        Db::startTrans();
        try {
            $process->save([
                'name' => $data['name'],
                'description' => $data['description'] ?? '',
                'status' => $data['status'] ?? 1,
                'updatetime' => time()
            ]);
            
            Db::commit();
            $this->success('更新成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('更新失败：' . $e->getMessage());
        }
    }

    /**
     * 删除工序
     */
    public function deleteProcess()
    {
        $processId = $this->request->post('id');
        if (!$processId) {
            $this->error('参数错误');
        }
        
        $process = Process::find($processId);
        if (!$process) {
            $this->error('工序不存在');
        }
        
        // 检查是否有关联的工序工价
        $priceCount = \app\admin\model\scanwork\ProcessPrice::where('process_id', $processId)->count();
        if ($priceCount > 0) {
            $this->error("工序【{$process->name}】下还有{$priceCount}个工价设置，请先删除相关工价");
        }
        
        Db::startTrans();
        try {
            $process->delete();
            Db::commit();
            $this->success('删除成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('删除失败：' . $e->getMessage());
        }
    }

    // ==================== 工序工价管理 ====================
    
    /**
     * 获取工序工价列表
     */
    public function getProcessPriceList()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $model_id = $this->request->get('model_id', '');
        $process_id = $this->request->get('process_id', '');
        
        $where = [];
        if ($model_id) {
            $where['model_id'] = $model_id;
        }
        if ($process_id) {
            $where['process_id'] = $process_id;
        }
        
        $list = \app\admin\model\scanwork\ProcessPrice::with(['model.product', 'process'])
            ->where($where)
            ->order('id', 'desc')
            ->paginate($limit, false, ['page' => $page]);
        
        $this->success('获取成功', [
            'list' => $list->items(),
            'total' => $list->total(),
            'page' => $page,
            'limit' => $limit
        ]);
    }

    /**
     * 创建工序工价
     */
    public function createProcessPrice()
    {
        $data = $this->request->post();
        
        if (empty($data['model_id']) || empty($data['process_id']) || !isset($data['price'])) {
            $this->error('型号、工序和工价不能为空');
        }
        
        // 检查是否已存在相同的型号+工序组合
        $exists = \app\admin\model\scanwork\ProcessPrice::where([
            'model_id' => $data['model_id'],
            'process_id' => $data['process_id']
        ])->find();
        if ($exists) {
            $this->error('该型号的此工序工价已存在，请勿重复设置');
        }
        
        Db::startTrans();
        try {
            $processPrice = \app\admin\model\scanwork\ProcessPrice::create([
                'model_id' => $data['model_id'],
                'process_id' => $data['process_id'],
                'price' => $data['price'],
                'time_price' => $data['time_price'] ?? 0,
                'status' => $data['status'] ?? 1,
                'createtime' => time(),
                'updatetime' => time()
            ]);
            
            Db::commit();
            $this->success('创建成功', $processPrice);
        } catch (Exception $e) {
            Db::rollback();
            $this->error('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 更新工序工价
     */
    public function updateProcessPrice()
    {
        $priceId = $this->request->post('id');
        $data = $this->request->post();
        
        if (!$priceId || empty($data['model_id']) || empty($data['process_id']) || !isset($data['price'])) {
            $this->error('参数错误');
        }
        
        $processPrice = \app\admin\model\scanwork\ProcessPrice::find($priceId);
        if (!$processPrice) {
            $this->error('工价记录不存在');
        }
        
        // 检查是否已存在相同的型号+工序组合（排除当前记录）
        $exists = \app\admin\model\scanwork\ProcessPrice::where([
            'model_id' => $data['model_id'],
            'process_id' => $data['process_id']
        ])->where('id', '<>', $priceId)->find();
        if ($exists) {
            $this->error('该型号的此工序工价已存在，请勿重复设置');
        }
        
        Db::startTrans();
        try {
            $processPrice->save([
                'model_id' => $data['model_id'],
                'process_id' => $data['process_id'],
                'price' => $data['price'],
                'time_price' => $data['time_price'] ?? 0,
                'status' => $data['status'] ?? 1,
                'updatetime' => time()
            ]);
            
            Db::commit();
            $this->success('更新成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('更新失败：' . $e->getMessage());
        }
    }

    /**
     * 删除工序工价
     */
    public function deleteProcessPrice()
    {
        $priceId = $this->request->post('id');
        if (!$priceId) {
            $this->error('参数错误');
        }
        
        $processPrice = \app\admin\model\scanwork\ProcessPrice::find($priceId);
        if (!$processPrice) {
            $this->error('工价记录不存在');
        }
        
        Db::startTrans();
        try {
            $processPrice->delete();
            Db::commit();
            $this->success('删除成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('删除失败：' . $e->getMessage());
        }
    }

    /**
     * 批量设置工序工价
     */
    public function batchProcessPrice()
    {
        $data = $this->request->post();
        
        if (empty($data['model_id']) || empty($data['prices'])) {
            $this->error('参数错误');
        }
        
        $modelId = $data['model_id'];
        $prices = $data['prices'];
        $timePrices = $data['time_prices'] ?? [];
        
        Db::startTrans();
        try {
            $successCount = 0;
            $failCount = 0;
            
            foreach ($prices as $processId => $price) {
                if ($price && $price > 0) {
                    // 检查是否已存在
                    $exists = \app\admin\model\scanwork\ProcessPrice::where([
                        'model_id' => $modelId,
                        'process_id' => $processId
                    ])->find();
                    
                    $timePrice = isset($timePrices[$processId]) ? $timePrices[$processId] : 0;
                    
                    if ($exists) {
                        // 更新现有记录
                        $exists->save(['price' => $price, 'time_price' => $timePrice]);
                    } else {
                        // 创建新记录
                        \app\admin\model\scanwork\ProcessPrice::create([
                            'model_id' => $modelId,
                            'process_id' => $processId,
                            'price' => $price,
                            'time_price' => $timePrice,
                            'status' => 1,
                            'createtime' => time(),
                            'updatetime' => time()
                        ]);
                    }
                    $successCount++;
                } else {
                    $failCount++;
                }
            }
            
            Db::commit();
            $this->success("批量设置完成：成功 {$successCount} 条，失败 {$failCount} 条");
        } catch (Exception $e) {
            Db::rollback();
            $this->error('批量设置失败：' . $e->getMessage());
        }
    }

    /**
     * 获取管理员权限信息（用于登录时返回）
     * @param int $adminId 管理员ID
     * @return array
     */
    private function getAdminPermissionsInfo($adminId)
    {
        try {
            // 使用新的简单权限系统
            $permission = \app\common\library\SimplePermission::instance();
            $ruleList = $permission->getAdminPermissions($adminId);
            
            \think\Log::info('获取管理员权限信息 - 管理员ID: ' . $adminId . ', 权限: ' . json_encode($ruleList));
            
            return [
                'is_super_admin' => $adminId == 1,
                'rule_list' => $ruleList,
                'permissions' => $this->formatPermissions($ruleList)
            ];
            
        } catch (\Exception $e) {
            \think\Log::error('获取管理员权限信息异常: ' . $e->getMessage());
            return [
                'is_super_admin' => false,
                'rule_list' => [],
                'permissions' => []
            ];
        }
    }
    
    /**
     * 格式化权限数据
     */
    private function formatPermissions($ruleList)
    {
        $permissions = [];
        foreach ($ruleList as $rule) {
            $parts = explode('/', $rule);
            if (count($parts) == 2) {
                $module = $parts[0];
                $action = $parts[1];
                
                if (!isset($permissions[$module])) {
                    $permissions[$module] = [];
                }
                $permissions[$module][] = $action;
            }
        }
        return $permissions;
    }

    /**
     * 获取所有可用权限
     */
    public function getAllPermissions()
    {
        try {
            $permission = \app\common\library\SimplePermission::instance();
            $permissions = $permission->getAllPermissions();
            
            $this->success('获取成功', $permissions);
            
        } catch (\Exception $e) {
            \think\Log::error('获取所有权限异常: ' . $e->getMessage());
            $this->error('获取权限失败');
        }
    }
    
    /**
     * 设置管理员权限
     */
    public function setAdminPermissions()
    {
        \think\Log::info('setAdminPermissions - 方法开始执行');
        
        try {
            // 使用更安全的方式获取参数
            $input = $this->request->getContent();
            \think\Log::info('setAdminPermissions - 原始请求数据: ' . $input);
            
            $data = json_decode($input, true);
            if (!$data) {
                $data = $this->request->param();
            }
            
            $adminId = isset($data['admin_id']) ? $data['admin_id'] : null;
            $permissions = isset($data['permissions']) ? $data['permissions'] : [];
            
            \think\Log::info('setAdminPermissions - 解析后的参数: admin_id=' . $adminId . ', permissions=' . json_encode($permissions));
            
            if (!$adminId) {
                \think\Log::error('setAdminPermissions - 管理员ID为空');
                $this->error('管理员ID不能为空');
            }
            
            \think\Log::info('setAdminPermissions - 参数验证通过，开始处理权限数据');
            
            // 尝试恢复session
            $adminInfo = session('admin_info');
            $adminToken = session('admin_token');
            
            \think\Log::info('setAdminPermissions - 初始session状态: admin_info=' . json_encode($adminInfo) . ', adminToken=' . $adminToken);
            
            // 如果没有session，尝试通过token恢复
            if (!$adminInfo || !$adminToken) {
                $token = $this->request->header('Authorization');
                \think\Log::info('setAdminPermissions - 没有session，尝试通过token恢复，token: ' . $token);
                
                if ($token) {
                    // 处理Bearer token格式
                    if (strpos($token, 'Bearer ') === 0) {
                        $token = substr($token, 7);
                    }
                    
                    // 验证token并获取管理员信息
                    $admin = \app\admin\model\Admin::where('token', $token)->find();
                    
                    \think\Log::info('setAdminPermissions - token验证结果: ' . ($admin ? '找到管理员，状态: ' . $admin->status : '未找到管理员'));
                    
                    // 如果没找到，尝试查找所有管理员的token
                    if (!$admin) {
                        $allAdmins = \app\admin\model\Admin::where('token', '<>', '')->field('id,username,token')->select();
                        \think\Log::info('setAdminPermissions - 数据库中所有token: ' . json_encode($allAdmins));
                    }
                    
                    if ($admin && ($admin->status === 'normal' || $admin->status === 1 || $admin->status === '1' || $admin->status === 'active')) {
                        $adminInfo = [
                            'id' => $admin->id,
                            'username' => $admin->username,
                            'nickname' => $admin->nickname ?: $admin->username,
                            'avatar' => $admin->avatar ?: '',
                            'is_admin' => true
                        ];
                        $adminToken = $token;
                        
                        // 设置session
                        session('admin_info', $adminInfo);
                        session('admin_token', $adminToken);
                        
                        \think\Log::info('setAdminPermissions - session恢复成功: ' . json_encode($adminInfo));
                    } else {
                        \think\Log::warning('setAdminPermissions - Token验证失败 - 请求token: ' . $token);
                    }
                }
            }
            
            // 检查权限 - 只有超级管理员或有管理员管理权限的管理员才能设置权限
            $currentAdminId = $adminInfo ? $adminInfo['id'] : null;
            
            \think\Log::info('setAdminPermissions - session信息: admin_info=' . json_encode($adminInfo) . ', currentAdminId=' . $currentAdminId);
            
            if (!$currentAdminId) {
                \think\Log::error('setAdminPermissions - 未找到当前管理员ID，session可能已过期');
                $response = [
                    'code' => 0,
                    'msg' => '请先登录',
                    'time' => time(),
                    'data' => null
                ];
                header('Content-Type: application/json');
                echo json_encode($response);
                exit;
            }
            
            // 超级管理员（ID为1）可以设置任何人的权限
            if ($currentAdminId != 1) {
                // 检查是否有管理员管理权限
                $permission = \app\common\library\SimplePermission::instance();
                if (!$permission->checkPermission($currentAdminId, 'admin_manage/edit')) {
                    \think\Log::warning('setAdminPermissions - 权限检查失败，管理员ID: ' . $currentAdminId . ', 需要权限: admin_manage/edit');
                    $response = [
                        'code' => 0,
                        'msg' => '您没有权限设置管理员权限',
                        'time' => time(),
                        'data' => null
                    ];
                    header('Content-Type: application/json');
                    echo json_encode($response);
                    exit;
                }
            }
            
            \think\Log::info('setAdminPermissions - 权限检查通过，开始设置权限');
            
            // 处理权限数据格式
            $formattedPermissions = [];
            if (is_array($permissions)) {
                foreach ($permissions as $perm) {
                    if (is_string($perm) && strpos($perm, '/') !== false) {
                        // 字符串格式: "module/action"
                        list($module, $action) = explode('/', $perm, 2);
                        $formattedPermissions[] = [
                            'module' => $module,
                            'action' => $action,
                            'granted' => true
                        ];
                    } elseif (is_array($perm) && isset($perm['module']) && isset($perm['action'])) {
                        // 对象格式: {module: 'xxx', action: 'xxx'}
                        $formattedPermissions[] = [
                            'module' => $perm['module'],
                            'action' => $perm['action'],
                            'granted' => isset($perm['granted']) ? $perm['granted'] : true
                        ];
                    }
                }
            }
            
            \think\Log::info('setAdminPermissions - 格式化后的权限: ' . json_encode($formattedPermissions));
            
            $permission = \app\common\library\SimplePermission::instance();
            $result = $permission->setAdminPermissions($adminId, $formattedPermissions);
            
            if ($result) {
                \think\Log::info('setAdminPermissions - 权限设置成功');
                $response = [
                    'code' => 1,
                    'msg' => '权限设置成功',
                    'time' => time(),
                    'data' => null
                ];
            } else {
                \think\Log::error('setAdminPermissions - 权限设置失败');
                $response = [
                    'code' => 0,
                    'msg' => '权限设置失败',
                    'time' => time(),
                    'data' => null
                ];
            }
            
            \think\Log::info('setAdminPermissions - 返回响应: ' . json_encode($response));
            
            // 直接输出JSON并退出
            header('Content-Type: application/json');
            echo json_encode($response);
            exit;
            
        } catch (\Exception $e) {
            \think\Log::error('设置管理员权限异常: ' . $e->getMessage() . ', 堆栈: ' . $e->getTraceAsString());
            $this->error('权限设置失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取管理员权限信息
     */
    public function getAdminPermissions()
    {
        // 直接使用session，不进行额外验证
        $adminInfo = session('admin_info');
        
        if (!$adminInfo) {
            $this->error('请先登录', null, 401);
        }

        try {
            $adminId = $adminInfo['id'];
            
            // 使用FastAdmin权限系统获取权限信息
            $permissions = $this->getAdminPermissionsInfo($adminId);
            
            // 获取管理员基本信息
            $admin = \app\admin\model\Admin::get($adminId);
            if (!$admin) {
                $this->error('获取管理员信息失败');
            }
            
            $this->success('获取成功', [
                'admin_id' => $adminId,
                'admin_username' => $adminInfo['username'],
                'admin_name' => $admin->nickname ?: $admin->username,
                'admin_description' => '基于FastAdmin权限系统',
                'permissions' => $permissions['permissions'],
                'is_super_admin' => $permissions['is_super_admin'],
                'rule_list' => $permissions['rule_list']
            ]);
        } catch (\Exception $e) {
            \think\Log::error('获取权限信息失败：' . $e->getMessage());
            $this->error('获取权限信息失败：' . $e->getMessage());
        }
    }

    /**
     * 检查管理员权限 - 使用FastAdmin权限系统
     * @param string $action 操作名称
     * @param int $adminId 管理员ID
     */
    private function checkPermission($action, $adminId)
    {
        try {
            // 使用新的简单权限系统
            $permission = \app\common\library\SimplePermission::instance();
            
            if (!$permission->checkPermission($adminId, $action)) {
                \think\Log::warning("权限检查失败 - 管理员ID: {$adminId}, 操作: {$action}");
                $this->error('您没有权限执行此操作', null, 403);
            }
            
            \think\Log::info("权限检查通过 - 管理员ID: {$adminId}, 操作: {$action}");
            return true;

        } catch (\Exception $e) {
            \think\Log::error("权限检查异常 - 管理员ID: {$adminId}, 操作: {$action}, 错误: " . $e->getMessage());
            $this->error('权限检查失败', null, 403);
        }
    }

    /**
     * 获取API操作与PC端权限规则的映射关系
     * @return array
     */
    private function getApiRuleMapping()
    {
        return [
            // 产品管理
            'getProductList' => 'scanwork/product/index',
            'createProduct' => 'scanwork/product/add',
            'updateProduct' => 'scanwork/product/edit',
            'deleteProduct' => 'scanwork/product/del',
            
            // 产品型号管理
            'getProductModelList' => 'scanwork/productmodel/index',
            'createProductModel' => 'scanwork/productmodel/add',
            'updateProductModel' => 'scanwork/productmodel/edit',
            'deleteProductModel' => 'scanwork/productmodel/del',
            
            // 工序管理
            'getProcessList' => 'scanwork/process/index',
            'createProcess' => 'scanwork/process/add',
            'updateProcess' => 'scanwork/process/edit',
            'deleteProcess' => 'scanwork/process/del',
            
            // 工价管理
            'getProcessPriceList' => 'scanwork/processprice/index',
            'createProcessPrice' => 'scanwork/processprice/add',
            'updateProcessPrice' => 'scanwork/processprice/edit',
            'deleteProcessPrice' => 'scanwork/processprice/del',
            'batchProcessPrice' => 'scanwork/processprice/batch',
            
            // 订单管理
            'getOrders' => 'scanwork/order/index',
            'getOrderDetail' => 'scanwork/order/detail',
            'createOrder' => 'scanwork/order/add',
            'updateOrder' => 'scanwork/order/edit',
            'deleteOrder' => 'scanwork/order/del',
            'getOrderProgressList' => 'scanwork/order/progress',
            'getProcessProgressStats' => 'scanwork/order/progress',
            'getOrderProgressDetail' => 'scanwork/order/progress',
            'getProgressFilterOptions' => 'scanwork/order/progress',
            
            // 分工管理
            'getAllocations' => 'scanwork/allocation/index',
            'getAllocationDetail' => 'scanwork/allocation/detail',
            'createAllocation' => 'scanwork/allocation/add',
            'batchCreateAllocation' => 'scanwork/allocation/batch',
            
            // 报工管理
            'getReports' => 'scanwork/report/index',
            'getReportDetail' => 'scanwork/report/detail',
            'auditReport' => 'scanwork/report/audit',
            'getActiveReports' => 'scanwork/activereport/index',
            'getActiveReportDetail' => 'scanwork/activereport/detail',
            'auditActiveReport' => 'scanwork/activereport/audit',
            
            // 生产计划管理
            'getProductionPlans' => 'scanwork/productionplan/index',
            'createProductionPlan' => 'scanwork/productionplan/add',
            'updateProductionPlan' => 'scanwork/productionplan/edit',
            'deleteProductionPlan' => 'scanwork/productionplan/del',
            'getProductionPlanDetail' => 'scanwork/productionplan/detail',
            'getProductionPlanAllocations' => 'scanwork/productionplan/allocations',
            'allocateProductionPlan' => 'scanwork/productionplan/allocate',
            'batchAllocateProductionPlan' => 'scanwork/productionplan/batch_allocate',
            'saveBatchAllocateProductionPlan' => 'scanwork/productionplan/batch_allocate',
            'getProductionPlanProgress' => 'scanwork/productionplan/progress',
            'startProductionPlan' => 'scanwork/productionplan/start',
            'pauseProductionPlan' => 'scanwork/productionplan/pause',
            'resumeProductionPlan' => 'scanwork/productionplan/resume',
            'completeProductionPlan' => 'scanwork/productionplan/complete',
            'updateProductionPlanProgress' => 'scanwork/productionplan/progress',
            'getProductionPlanStats' => 'scanwork/productionplan/stats',
            'generateProductionPlanFromOrder' => 'scanwork/productionplan/generate',
            'getOrderProducts' => 'scanwork/productionplan/order_products',
            'getProductAvailableQuantity' => 'scanwork/productionplan/quantity',
            
            // 管理员管理
            'getAdminList' => 'auth/admin/index',
            'createAdmin' => 'auth/admin/add',
            'updateAdmin' => 'auth/admin/edit',
            'deleteAdmin' => 'auth/admin/del',
            'getAdminDetail' => 'auth/admin/detail',
            'getAllAdminPermissions' => 'auth/admin/index',
            
            // 用户管理
            'getUsers' => 'scanwork/user/index',
            'getUserList' => 'scanwork/user/index',
            'updateUser' => 'scanwork/user/edit',
            'deleteUser' => 'scanwork/user/del',
            'changeUserPassword' => 'scanwork/user/password',
            'getAvailableUsers' => 'scanwork/user/index',
            'addProcessUsers' => 'scanwork/user/add',
            'removeProcessUser' => 'scanwork/user/del',
            'getProcessUsers' => 'scanwork/user/index',
            
            // 基础数据
            'getProducts' => 'scanwork/product/index',
            'getProcesses' => 'scanwork/process/index',
            'getModels' => 'scanwork/productmodel/index',
            'getOrderModels' => 'scanwork/order/index',
            
            // 文件上传
            'uploadAuditImage' => 'scanwork/report/audit',
            'uploadAuditVideo' => 'scanwork/report/audit',
        ];
    }

    /**
     * 获取管理员所属的管理组ID
     * @param int $adminId 管理员ID
     * @return int 管理组ID
     */
    private function getAdminGroupId($adminId)
    {
        try {
            // 从fa_auth_group_access表获取管理员所属的管理组
            $groupAccess = Db::name('auth_group_access')
                ->where('uid', $adminId)
                ->find();
            
            if ($groupAccess) {
                return $groupAccess['group_id'];
            }
            
            // 如果没有找到，返回默认管理组ID
            return 5; // 默认只读管理组
        } catch (\Exception $e) {
            \think\Log::error("获取管理员管理组失败 - 管理员ID: {$adminId}, 错误: " . $e->getMessage());
            return 5; // 默认只读管理组
        }
    }

    /**
     * 获取管理组权限配置
     * @param int $groupId 管理组ID
     * @return array 权限配置
     */
    private function getGroupPermissions($groupId)
    {
        $permissionConfig = config('miniprogram_permissions');
        
        // 获取默认权限配置
        $defaultPermissions = $permissionConfig['default_group_permissions'];
        
        // 如果是超级管理组
        if ($groupId == 1) {
            return $defaultPermissions[1];
        }
        
        // 其他管理组使用默认权限（只读）
        return $defaultPermissions['default'];
    }

    /**
     * 获取管理组名称
     * @param int $groupId 管理组ID
     * @return string 管理组名称
     */
    private function getGroupName($groupId)
    {
        try {
            // 从fa_auth_group表获取管理组名称
            $group = Db::name('auth_group')
                ->where('id', $groupId)
                ->field('name,title')
                ->find();
            
            if ($group) {
                return $group['title'] ?: $group['name'];
            }
            
            // 如果没有找到，返回默认名称
            return '默认管理组';
        } catch (\Exception $e) {
            \think\Log::error("获取管理组名称失败 - 管理组ID: {$groupId}, 错误: " . $e->getMessage());
            return '默认管理组';
        }
    }

    /**
     * 获取订单进度列表
     */
    public function getOrderProgressList()
    {
        try {
            $page = $this->request->get('page', 1);
            $limit = $this->request->get('limit', 10);
            $orderId = $this->request->get('order_id', '');
            $productId = $this->request->get('product_id', '');
            $processId = $this->request->get('process_id', '');

            $where = [];
            if ($orderId) $where['o.id'] = $orderId;
            if ($productId) $where['m.product_id'] = $productId;
            if ($processId) $where['a.process_id'] = $processId;

            // 查询订单进度数据
            $query = Db::name('scanwork_order')
                ->alias('o')
                ->join('scanwork_order_model om', 'o.id = om.order_id')
                ->join('scanwork_model m', 'om.model_id = m.id')
                ->join('scanwork_product p', 'm.product_id = p.id')
                ->join('scanwork_allocation a', 'o.id = a.order_id AND om.model_id = a.model_id', 'LEFT')
                ->field('o.id, o.order_no, o.customer_name, o.status, o.createtime, 
                        p.name as product_name, m.name as model_name, m.id as model_id,
                        om.quantity as order_quantity,
                        IFNULL(SUM(a.quantity), 0) as allocated_quantity,
                        IFNULL(SUM(a.reported_quantity), 0) as reported_quantity')
                ->where($where)
                ->group('o.id, om.model_id');

            $total = $query->count();
            $list = $query->page($page, $limit)->select();

            // 计算进度
            foreach ($list as &$item) {
                $item['progress'] = $item['allocated_quantity'] > 0 ? 
                    round(($item['reported_quantity'] / $item['allocated_quantity']) * 100, 2) : 0;
                $item['status_text'] = $this->getOrderStatusText($item['status']);
                $item['createtime_text'] = date('Y-m-d', $item['createtime']);
            }

            $this->success('获取成功', [
                'list' => $list,
                'total' => $total,
                'page' => $page,
                'limit' => $limit
            ]);

        } catch (\Exception $e) {
            \think\Log::error('获取订单进度列表失败: ' . $e->getMessage());
            $this->error('获取订单进度列表失败');
        }
    }

    /**
     * 获取工序进度统计
     */
    public function getProcessProgressStats()
    {
        try {
            $orderId = $this->request->get('order_id', '');
            $productId = $this->request->get('product_id', '');
            $processId = $this->request->get('process_id', '');

            $where = [];
            if ($orderId) $where['a.order_id'] = $orderId;
            if ($productId) $where['m.product_id'] = $productId;
            if ($processId) $where['a.process_id'] = $processId;

            // 查询工序进度统计
            $stats = Db::name('scanwork_allocation')
                ->alias('a')
                ->join('scanwork_model m', 'a.model_id = m.id')
                ->join('scanwork_process p', 'a.process_id = p.id')
                ->field('p.id as process_id, p.name as process_name, 
                        SUM(a.quantity) as total_quantity,
                        SUM(a.reported_quantity) as reported_quantity')
                ->where($where)
                ->group('a.process_id')
                ->select();

            // 计算完成率
            foreach ($stats as &$item) {
                $item['completion_rate'] = $item['total_quantity'] > 0 ? 
                    round(($item['reported_quantity'] / $item['total_quantity']) * 100, 2) : 0;
            }

            $this->success('获取成功', $stats);

        } catch (\Exception $e) {
            \think\Log::error('获取工序进度统计失败: ' . $e->getMessage());
            $this->error('获取工序进度统计失败');
        }
    }

    /**
     * 获取订单进度详情
     */
    public function getOrderProgressDetail()
    {
        try {
            $orderId = $this->request->get('order_id');
            if (!$orderId) {
                $this->error('订单ID不能为空');
            }

            // 获取订单基本信息
            $order = Db::name('scanwork_order')
                ->alias('o')
                ->field('o.*, 
                        SUM(om.quantity) as total_order_quantity,
                        SUM(a.quantity) as total_allocated_quantity,
                        SUM(a.reported_quantity) as total_reported_quantity')
                ->join('scanwork_order_model om', 'o.id = om.order_id', 'LEFT')
                ->join('scanwork_allocation a', 'o.id = a.order_id', 'LEFT')
                ->where('o.id', $orderId)
                ->group('o.id')
                ->find();

            if (!$order) {
                $this->error('订单不存在');
            }

            // 计算总体进度
            $order['total_progress'] = $order['total_allocated_quantity'] > 0 ? 
                round(($order['total_reported_quantity'] / $order['total_allocated_quantity']) * 100, 2) : 0;

            // 获取订单型号进度
            $orderModels = Db::name('scanwork_order_model')
                ->alias('om')
                ->join('scanwork_model m', 'om.model_id = m.id')
                ->join('scanwork_product p', 'm.product_id = p.id')
                ->field('om.*, m.name as model_name, p.name as product_name,
                        IFNULL(SUM(a.quantity), 0) as allocated_quantity,
                        IFNULL(SUM(a.reported_quantity), 0) as reported_quantity')
                ->join('scanwork_allocation a', 'om.order_id = a.order_id AND om.model_id = a.model_id', 'LEFT')
                ->where('om.order_id', $orderId)
                ->group('om.id')
                ->select();

            // 计算型号进度
            foreach ($orderModels as &$model) {
                $model['progress'] = $model['allocated_quantity'] > 0 ? 
                    round(($model['reported_quantity'] / $model['allocated_quantity']) * 100, 2) : 0;
            }

            // 获取分工分配详情
            $allocations = Db::name('scanwork_allocation')
                ->alias('a')
                ->join('scanwork_model m', 'a.model_id = m.id')
                ->join('scanwork_product p', 'm.product_id = p.id')
                ->join('scanwork_process pr', 'a.process_id = pr.id')
                ->join('fa_admin u', 'a.user_id = u.id')
                ->field('a.*, m.name as model_name, p.name as product_name, 
                        pr.name as process_name, u.nickname as user_name,
                        (a.quantity - a.reported_quantity) as remaining_quantity')
                ->where('a.order_id', $orderId)
                ->select();

            // 计算分配进度
            foreach ($allocations as &$allocation) {
                $allocation['progress'] = $allocation['quantity'] > 0 ? 
                    round(($allocation['reported_quantity'] / $allocation['quantity']) * 100, 2) : 0;
                $allocation['status_text'] = $allocation['status'] == 0 ? '进行中' : '已完成';
            }

            $this->success('获取成功', [
                'order' => $order,
                'orderModels' => $orderModels,
                'allocations' => $allocations
            ]);

        } catch (\Exception $e) {
            \think\Log::error('获取订单进度详情失败: ' . $e->getMessage());
            $this->error('获取订单进度详情失败');
        }
    }

    /**
     * 获取筛选选项
     */
    public function getProgressFilterOptions()
    {
        try {
            // 获取订单列表
            $orders = Db::name('scanwork_order')
                ->field('id, order_no')
                ->order('createtime desc')
                ->select();

            // 获取产品列表
            $products = Db::name('scanwork_product')
                ->field('id, name')
                ->where('status', 1)
                ->select();

            // 获取工序列表
            $processes = Db::name('scanwork_process')
                ->field('id, name')
                ->where('status', 1)
                ->select();

            $this->success('获取成功', [
                'orders' => $orders,
                'products' => $products,
                'processes' => $processes
            ]);

        } catch (\Exception $e) {
            \think\Log::error('获取筛选选项失败: ' . $e->getMessage());
            $this->error('获取筛选选项失败');
        }
    }

    /**
     * 获取订单状态文本
     */
    private function getOrderStatusText($status)
    {
        $statusMap = [
            0 => '待生产',
            1 => '生产中',
            2 => '已完成'
        ];
        return $statusMap[$status] ?? '未知状态';
    }

    // ==================== 管理员管理 ====================
    
    /**
     * 获取管理员列表
     */
    public function getAdminList()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $username = $this->request->get('username', '');
        $status = $this->request->get('status', '');
        
        $where = [];
        if ($username) {
            $where[] = ['username', 'like', '%' . $username . '%'];
        }
        if ($status !== '') {
            $where[] = ['status', '=', $status];
        }
        
        $list = AdminModel::where($where)
            ->field('id, username, nickname, status, createtime, updatetime')
            ->order('id', 'desc')
            ->paginate($limit, false, ['page' => $page]);
        
        $this->success('获取成功', [
            'list' => $list->items(),
            'total' => $list->total(),
            'page' => $page,
            'limit' => $limit
        ]);
    }

    /**
     * 创建管理员
     */
    public function createAdmin()
    {
        $data = $this->request->post();
        
        if (empty($data['username']) || empty($data['nickname']) || empty($data['password'])) {
            $this->error('用户名、昵称和密码不能为空');
        }
        
        // 检查用户名是否已存在
        $exists = AdminModel::where('username', $data['username'])->find();
        if ($exists) {
            $this->error('用户名已存在');
        }
        
        Db::startTrans();
        try {
            // 生成盐值
            $salt = $this->random_string(6);
            
            // 创建管理员
            $admin = AdminModel::create([
                'username' => $data['username'],
                'nickname' => $data['nickname'],
                'password' => md5(md5($data['password']) . $salt),
                'salt' => $salt,
                'status' => $data['status'] ?? 1,
                'createtime' => time(),
                'updatetime' => time()
            ]);
            
            // 保存权限配置到配置文件
            if (!empty($data['permissions'])) {
                $this->saveAdminPermissions($admin->id, $data['permissions']);
            }
            
            Db::commit();
            $this->success('创建成功', $admin);
        } catch (Exception $e) {
            Db::rollback();
            $this->error('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 更新管理员
     */
    public function updateAdmin()
    {
        $data = $this->request->post();
        
        if (empty($data['id']) || empty($data['nickname'])) {
            $this->error('参数错误');
        }
        
        $admin = AdminModel::find($data['id']);
        if (!$admin) {
            $this->error('管理员不存在');
        }
        
        // 不能修改超级管理员
        if ($admin->id == 1) {
            $this->error('不能修改超级管理员');
        }
        
        Db::startTrans();
        try {
            $updateData = [
                'nickname' => $data['nickname'],
                'status' => $data['status'] ?? 1,
                'updatetime' => time()
            ];
            
                            // 如果提供了新密码，则更新密码
                if (!empty($data['password'])) {
                    $salt = $this->random_string(6);
                    $updateData['password'] = md5(md5($data['password']) . $salt);
                    $updateData['salt'] = $salt;
                }
            
            $admin->save($updateData);
            
            // 保存权限配置到配置文件
            if (!empty($data['permissions'])) {
                $this->saveAdminPermissions($admin->id, $data['permissions']);
            }
            
            Db::commit();
            $this->success('更新成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('更新失败：' . $e->getMessage());
        }
    }

    /**
     * 删除管理员
     */
    public function deleteAdmin()
    {
        $adminId = $this->request->post('id');
        if (!$adminId) {
            $this->error('参数错误');
        }
        
        $admin = AdminModel::find($adminId);
        if (!$admin) {
            $this->error('管理员不存在');
        }
        
        // 不能删除超级管理员
        if ($admin->id == 1) {
            $this->error('不能删除超级管理员');
        }
        
        Db::startTrans();
        try {
            $admin->delete();
            
            // 从权限配置中删除该管理员
            $this->removeAdminPermissions($adminId);
            
            Db::commit();
            $this->success('删除成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('删除失败：' . $e->getMessage());
        }
    }

    /**
     * 获取管理员详情
     */
    public function getAdminDetail()
    {
        $adminId = $this->request->get('id');
        \think\Log::info("getAdminDetail - 方法被调用，管理员ID: {$adminId}");
        
        if (!$adminId) {
            $this->error('参数错误');
        }
        
        $admin = AdminModel::find($adminId);
        if (!$admin) {
            $this->error('管理员不存在');
        }
        
        // 获取权限配置
        \think\Log::info("getAdminDetail - 准备调用getAdminPermissionsInfo，管理员ID: {$adminId}");
        $permissions = $this->getAdminPermissionsInfo($adminId);
        \think\Log::info("getAdminDetail - getAdminPermissionsInfo调用完成，返回权限: " . json_encode($permissions, JSON_UNESCAPED_UNICODE));
        
        $adminData = [
            'id' => $admin->id,
            'username' => $admin->username,
            'nickname' => $admin->nickname,
            'status' => $admin->status,
            'createtime' => $admin->createtime,
            'updatetime' => $admin->updatetime,
            'rule_list' => $permissions['rule_list'] ?? [],
            'is_super_admin' => $permissions['is_super_admin'] ?? false
        ];
        
        $this->success('获取成功', $adminData);
    }

    /**
     * 获取所有管理员权限配置
     */
    public function getAllAdminPermissions()
    {
        try {
            $configFile = APP_PATH . 'extra/miniprogram_permissions.php';
            $config = include $configFile;
            
            $adminPermissions = [];
            foreach ($config['admin_permissions'] as $adminId => $permission) {
                $admin = AdminModel::find($adminId);
                if ($admin) {
                    // 将关联数组转换为普通数组
                    $formattedPermissions = [];
                    foreach ($permission['permissions'] as $module => $actions) {
                        $formattedPermissions[$module] = array_values($actions);
                    }
                    
                    $adminPermissions[] = [
                        'id' => $adminId,
                        'username' => $admin->username,
                        'nickname' => $admin->nickname,
                        'name' => $permission['name'],
                        'description' => $permission['description'],
                        'permissions' => $formattedPermissions
                    ];
                }
            }
            
            $this->success('获取成功', $adminPermissions);
        } catch (Exception $e) {
            $this->error('获取权限配置失败：' . $e->getMessage());
        }
    }

    /**
     * 保存管理员权限到配置文件
     */
    private function saveAdminPermissions($adminId, $permissions)
    {
        try {
            $configFile = APP_PATH . 'extra/miniprogram_permissions.php';
            $config = include $configFile;
            
            // 将前端传来的数组格式转换为配置文件需要的格式
            $formattedPermissions = [];
            foreach ($permissions as $module => $actions) {
                if (is_array($actions)) {
                    $formattedPermissions[$module] = array_values($actions);
                } else {
                    $formattedPermissions[$module] = [];
                }
            }
            
            // 更新管理员权限配置
            $config['admin_permissions'][$adminId] = [
                'name' => '管理员' . $adminId,
                'description' => '自定义权限配置',
                'permissions' => $formattedPermissions
            ];
            
            // 写回配置文件
            $configContent = "<?php\n\nreturn " . var_export($config, true) . ";\n";
            file_put_contents($configFile, $configContent);
            
            \think\Log::info("管理员权限配置已更新 - 管理员ID: {$adminId}");
        } catch (Exception $e) {
            \think\Log::error("保存管理员权限配置失败 - 管理员ID: {$adminId}, 错误: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * 从权限配置中删除管理员
     */
    private function removeAdminPermissions($adminId)
    {
        try {
            $configFile = APP_PATH . 'extra/miniprogram_permissions.php';
            $config = include $configFile;
            
            // 删除管理员权限配置
            if (isset($config['admin_permissions'][$adminId])) {
                unset($config['admin_permissions'][$adminId]);
            }
            
            // 写回配置文件
            $configContent = "<?php\n\nreturn " . var_export($config, true) . ";\n";
            file_put_contents($configFile, $configContent);
            
            \think\Log::info("管理员权限配置已删除 - 管理员ID: {$adminId}");
        } catch (Exception $e) {
            \think\Log::error("删除管理员权限配置失败 - 管理员ID: {$adminId}, 错误: " . $e->getMessage());
            throw $e;
        }
    }


    /**
     * 生成随机字符串
     */
    private function random_string($length = 6)
    {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $str = '';
        for ($i = 0; $i < $length; $i++) {
            $str .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $str;
    }

    /**
     * 获取工序关联的员工列表
     */
    public function getProcessUsers()
    {
        $process_id = $this->request->get('process_id');
        
        if (!$process_id) {
            $this->error('请选择工序');
        }
        
        // 获取该工序关联的所有员工
        $users = Db::name('scanwork_process_user')
            ->alias('pu')
            ->join('user u', 'u.id = pu.user_id')
            ->where('pu.process_id', $process_id)
            ->where('pu.status', 1)
            ->field('u.id, u.nickname, u.avatar, u.mobile')
            ->select();
            
        $this->success('获取成功', $users);
    }

    /**
     * 获取可添加的员工列表（排除已关联的员工）
     */
    public function getAvailableUsers()
    {
        $process_id = $this->request->get('process_id');
        
        if (!$process_id) {
            $this->error('请选择工序');
        }
        
        // 获取所有员工
        $allUsers = Db::name('user')
            ->field('id, nickname, avatar, mobile')
            ->select();
            
        // 获取已关联的员工ID
        $relatedUserIds = Db::name('scanwork_process_user')
            ->where('process_id', $process_id)
            ->where('status', 1)
            ->column('user_id');
            
        // 过滤出可添加的员工
        $availableUsers = array_filter($allUsers, function($user) use ($relatedUserIds) {
            return !in_array($user['id'], $relatedUserIds);
        });
        
        $this->success('获取成功', array_values($availableUsers));
    }

    /**
     * 添加工序-员工关联
     */
    public function addProcessUsers()
    {
        $process_id = $this->request->post('process_id');
        $user_ids = $this->request->post('user_ids');
        
        \think\Log::info('addProcessUsers - 接收参数: process_id=' . $process_id . ', user_ids=' . json_encode($user_ids));
        \think\Log::info('addProcessUsers - user_ids类型: ' . gettype($user_ids));
        
        if (!$process_id) {
            $this->error('工序ID不能为空');
        }
        
        // 处理user_ids参数，可能是JSON字符串
        if (is_string($user_ids)) {
            $user_ids = json_decode($user_ids, true);
            \think\Log::info('addProcessUsers - 解析JSON后的user_ids: ' . json_encode($user_ids));
        }
        
        if (!is_array($user_ids)) {
            \think\Log::error('addProcessUsers - user_ids不是数组: ' . gettype($user_ids) . ', 值: ' . json_encode($user_ids));
            $this->error('用户ID必须是数组格式');
        }
        
        if (empty($user_ids)) {
            $this->error('用户ID数组不能为空');
        }
        
        Db::startTrans();
        try {
            $successCount = 0;
            foreach ($user_ids as $user_id) {
                // 验证用户ID
                if (!is_numeric($user_id)) {
                    \think\Log::warning('addProcessUsers - 跳过无效用户ID: ' . $user_id);
                    continue;
                }
                
                // 检查是否已存在
                $exists = Db::name('scanwork_process_user')
                    ->where('process_id', $process_id)
                    ->where('user_id', $user_id)
                    ->where('status', 1)
                    ->find();
                    
                if (!$exists) {
                    $insertData = [
                        'process_id' => intval($process_id),
                        'user_id' => intval($user_id),
                        'status' => 1,
                        'createtime' => time()
                    ];
                    
                    \think\Log::info('addProcessUsers - 插入数据: ' . json_encode($insertData));
                    
                    $result = Db::name('scanwork_process_user')->insert($insertData);
                    if ($result) {
                        $successCount++;
                    }
                } else {
                    \think\Log::info('addProcessUsers - 关联已存在，跳过: process_id=' . $process_id . ', user_id=' . $user_id);
                }
            }
            
            Db::commit();
            $this->success('添加成功，共添加' . $successCount . '个关联');
        } catch (Exception $e) {
            Db::rollback();
            \think\Log::error('addProcessUsers - 添加失败: ' . $e->getMessage());
            $this->error('添加失败：' . $e->getMessage());
        }
    }

    /**
     * 移除工序-员工关联
     */
    public function removeProcessUser()
    {
        $process_id = $this->request->post('process_id');
        $user_id = $this->request->post('user_id');
        
        if (!$process_id || !$user_id) {
            $this->error('参数错误');
        }
        
        try {
            Db::name('scanwork_process_user')
                ->where('process_id', $process_id)
                ->where('user_id', $user_id)
                ->update(['status' => 0, 'updatetime' => time()]);
                
            $this->success('移除成功');
        } catch (Exception $e) {
            $this->error('移除失败：' . $e->getMessage());
        }
    }

    /**
     * 获取追溯信息（用于前端页面）
     */
    public function getTraceInfo()
    {
        $traceCode = $this->request->get('id');
        
        if (!$traceCode) {
            return json(['code' => 0, 'msg' => '缺少追溯码参数']);
        }
        
        // 支持通过追溯码或ID查询
        if (is_numeric($traceCode)) {
            $where = 't.id = ' . intval($traceCode);
        } else {
            $where = "t.trace_code = '" . addslashes($traceCode) . "'";
        }

        // 先查询追溯码基本信息
        $trace = Db::name('scanwork_trace_codes')
            ->alias('t')
            ->where($where)
            ->find();

        if (!$trace) {
            return json(['code' => 0, 'msg' => '追溯码不存在或已失效']);
        }

        // 根据追溯码类型获取详细信息
        if ($trace['report_id']) {
            // 普通报工追溯码
            $trace = Db::name('scanwork_trace_codes')
                ->alias('t')
                ->join('fa_scanwork_report r', 't.report_id = r.id')
                ->join('fa_scanwork_allocation a', 'r.allocation_id = a.id')
                ->join('fa_scanwork_order o', 'a.order_id = o.id')
                ->join('fa_scanwork_model m', 'a.model_id = m.id')
                ->join('fa_scanwork_product p', 'm.product_id = p.id')
                ->join('fa_scanwork_process proc', 'a.process_id = proc.id')
                ->join('fa_user worker', 'r.user_id = worker.id')
                ->join('fa_user auditor', 'r.audit_user_id = auditor.id', 'LEFT')
                ->field('t.*, o.order_no, o.customer_name, m.name as model_name, m.model_code, p.name as product_name, proc.name as process_name, worker.nickname as worker_name, auditor.nickname as auditor_name, r.quantity, r.item_nos, r.remark, r.audit_time as report_audit_time, r.audit_reason, r.work_hours, r.wage, r.allocation_id')
                ->where($where)
                ->find();
        } elseif ($trace['active_report_id']) {
            // 主动报工追溯码
            $trace = Db::name('scanwork_trace_codes')
                ->alias('t')
                ->join('fa_scanwork_active_report ar', 't.active_report_id = ar.id')
                ->join('fa_scanwork_order o', 'ar.order_id = o.id')
                ->join('fa_scanwork_model m', 'ar.model_id = m.id')
                ->join('fa_scanwork_product p', 'm.product_id = p.id')
                ->join('fa_scanwork_process proc', 'ar.process_id = proc.id')
                ->join('fa_user worker', 'ar.user_id = worker.id')
                ->join('fa_user auditor', 'ar.audit_user_id = auditor.id', 'LEFT')
                ->field('t.*, o.order_no, o.customer_name, m.name as model_name, m.model_code, p.name as product_name, proc.name as process_name, worker.nickname as worker_name, auditor.nickname as auditor_name, ar.quantity, ar.work_hours, ar.total_wage, ar.remark, ar.audit_time as report_audit_time, ar.audit_reason')
                ->where($where)
                ->find();
        }

        if (!$trace) {
            return json(['code' => 0, 'msg' => '追溯码不存在或已失效']);
        }

        // 处理产品编号，解析JSON数组
        if ($trace && isset($trace['item_nos']) && $trace['item_nos']) {
            $itemNos = json_decode($trace['item_nos'], true);
            if (is_array($itemNos)) {
                $trace['item_nos_array'] = $itemNos;
            } else {
                $trace['item_nos_array'] = [$trace['item_nos']];
            }
        } else {
            $trace['item_nos_array'] = [];
        }

        // 获取每个产品编号的图片和视频
        $trace['item_media'] = [];
        
        if ($trace['report_id']) {
            // 普通报工的产品编号图片和视频
            foreach ($trace['item_nos_array'] as $itemNo) {
                $itemMedia = [
                    'item_no' => $itemNo,
                    'audit_images' => [],
                    'audit_videos' => []
                ];

                // 先通过item_no找到对应的item_id
                $productItem = Db::name('scanwork_product_item')
                    ->where('item_no', $itemNo)
                    ->where('allocation_id', $trace['allocation_id'])
                    ->find();

                if ($productItem) {
                    // 获取审核图片和视频（都存储在同一个表中）
                    $auditFiles = Db::name('scanwork_item_audit_image')
                        ->where('item_id', $productItem['id'])
                        ->where('report_id', $trace['report_id'])
                        ->field('image_url, createtime')
                        ->select();

                    // 根据文件扩展名分类图片和视频
                    foreach ($auditFiles as $file) {
                        $extension = strtolower(pathinfo($file['image_url'], PATHINFO_EXTENSION));
                        if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'])) {
                            $itemMedia['audit_images'][] = $file;
                        } elseif (in_array($extension, ['mp4', 'avi', 'mov', 'wmv', 'flv'])) {
                            $itemMedia['audit_videos'][] = $file;
                        }
                    }
                }

                $trace['item_media'][] = $itemMedia;
            }
        } elseif ($trace['active_report_id']) {
            // 主动报工的产品编号图片
            $activeReportItems = Db::name('scanwork_active_report_product_item')
                ->where('active_report_id', $trace['active_report_id'])
                ->field('item_no, image_url, createtime')
                ->select();
            
            // 按item_no分组
            $itemGroups = [];
            foreach ($activeReportItems as $item) {
                $itemNo = $item['item_no'];
                if (!isset($itemGroups[$itemNo])) {
                    $itemGroups[$itemNo] = [
                        'item_no' => $itemNo,
                        'audit_images' => [],
                        'audit_videos' => []
                    ];
                }
                
                // 根据文件扩展名分类图片和视频
                $extension = strtolower(pathinfo($item['image_url'], PATHINFO_EXTENSION));
                if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'])) {
                    $itemGroups[$itemNo]['audit_images'][] = [
                        'image_url' => $item['image_url'],
                        'createtime' => $item['createtime']
                    ];
                } elseif (in_array($extension, ['mp4', 'avi', 'mov', 'wmv', 'flv'])) {
                    $itemGroups[$itemNo]['audit_videos'][] = [
                        'image_url' => $item['image_url'],
                        'createtime' => $item['createtime']
                    ];
                }
            }
            
            $trace['item_media'] = array_values($itemGroups);
            
            // 为主动报工生成item_nos_array
            $trace['item_nos_array'] = array_keys($itemGroups);
        }

        // 获取报工图片（不按产品编号分组）
        if ($trace['report_id']) {
            // 普通报工图片
            $trace['report_images'] = Db::name('scanwork_report_image')
                ->where('report_id', $trace['report_id'])
                ->field('image_url, createtime')
                ->select();
        } elseif ($trace['active_report_id']) {
            // 主动报工图片
            $trace['report_images'] = Db::name('scanwork_active_report_image')
                ->where('active_report_id', $trace['active_report_id'])
                ->where('image_type', 1) // 员工上传的图片
                ->field('image_url, createtime')
                ->select();
        } else {
            $trace['report_images'] = [];
        }
        
        return json(['code' => 1, 'msg' => '获取成功', 'data' => $trace]);
    }
    
    /**
     * 审核通过后创建溯源码
     */
    private function createTraceCodeAfterAudit($report)
    {
        try {
            // 检查是否已经创建过溯源码
            $existingTrace = Db::name('scanwork_trace_codes')->where('report_id', $report->id)->find();
            if ($existingTrace) {
                return; // 已存在，直接返回
            }
            
            // 获取报工相关信息（使用已有的关联数据）
            $allocation = \app\admin\model\scanwork\Allocation::with(['order', 'model.product', 'process'])->find($report->allocation_id);
            if (!$allocation) {
                return;
            }
            
            // 获取员工和审核员信息（使用已有的关联数据）
            $worker = \app\common\model\User::find($report->user_id);
            $auditor = \app\common\model\User::find($report->audit_user_id);
            
            $productName = $allocation->model->product->name ?? '';
            $processName = $allocation->process->name ?? '';
            $workerName = $worker ? ($worker->nickname ?? $worker->username ?? '') : '';
            $auditorName = $auditor ? ($auditor->nickname ?? $auditor->username ?? '') : '';
            
            // 获取产品编号（如果有的话）
            $itemNo = '';
            $productItem = Db::name('scanwork_product_item')->where('report_id', $report->id)->find();
            if ($productItem) {
                $itemNo = $productItem['item_no'];
            }
            
            // 生成溯源码
            $prefix = 'TR';
            $date = date('Ymd');
            $time = date('His');
            $random = strtoupper(substr(md5(uniqid()), 0, 4));
            $traceCode = $prefix . $date . $time . $random;
            
            // 检查是否已存在
            while (Db::name('scanwork_trace_codes')->where('trace_code', $traceCode)->find()) {
                $random = strtoupper(substr(md5(uniqid()), 0, 4));
                $traceCode = $prefix . $date . $time . $random;
            }
            
            // 创建溯源码记录
            $traceData = [
                'trace_code' => $traceCode,
                'report_id' => $report->id,
                'product_name' => $productName,
                'item_no' => $itemNo,
                'process_name' => $processName,
                'worker_name' => $workerName,
                'auditor_name' => $auditorName,
                'remark' => '审核通过',
                'audit_time' => time(),
                'status' => 1,
                'createtime' => time(),
                'updatetime' => time()
            ];
            
            $traceId = Db::name('scanwork_trace_codes')->insertGetId($traceData);
            
            if ($traceId) {
                // 生成溯源码二维码图片
                $this->generateQrCodeImage($traceCode);
            }
            
        } catch (Exception $e) {
            // 静默处理异常，不影响审核流程
            \think\Log::error('创建溯源码异常 - 报工ID: ' . $report->id . ', 错误: ' . $e->getMessage());
        }
    }
    
    /**
     * 主动报工审核通过后创建溯源码
     */
    private function createTraceCodeAfterActiveAudit($activeReport)
    {
        try {
            // 检查是否已经创建过溯源码
            $existingTrace = Db::name('scanwork_trace_codes')->where('active_report_id', $activeReport['id'])->find();
            if ($existingTrace) {
                return; // 已存在，直接返回
            }
            
            // 获取主动报工相关信息
            $order = Db::name('scanwork_order')->where('id', $activeReport['order_id'])->find();
            $model = Db::name('scanwork_model')->where('id', $activeReport['model_id'])->find();
            $product = Db::name('scanwork_product')->where('id', $activeReport['product_id'])->find();
            $process = Db::name('scanwork_process')->where('id', $activeReport['process_id'])->find();
            $worker = Db::name('user')->where('id', $activeReport['user_id'])->find();
            $auditor = Db::name('user')->where('id', $activeReport['audit_user_id'])->find();
            
            $productName = $product ? $product['name'] : '';
            $processName = $process ? $process['name'] : '';
            $workerName = $worker ? ($worker['nickname'] ?? $worker['username'] ?? '') : '';
            $auditorName = $auditor ? ($auditor['nickname'] ?? $auditor['username'] ?? '') : '';
            
            // 生成溯源码
            $prefix = 'TR';
            $date = date('Ymd');
            $time = date('His');
            $random = strtoupper(substr(md5(uniqid()), 0, 4));
            $traceCode = $prefix . $date . $time . $random;
            
            // 检查是否已存在
            while (Db::name('scanwork_trace_codes')->where('trace_code', $traceCode)->find()) {
                $random = strtoupper(substr(md5(uniqid()), 0, 4));
                $traceCode = $prefix . $date . $time . $random;
            }
            
            // 获取主动报工的产品编号列表
            $itemNos = Db::name('scanwork_active_report_product_item')
                ->where('active_report_id', $activeReport['id'])
                ->field('DISTINCT item_no')
                ->select();
            
            $itemNoList = [];
            foreach ($itemNos as $item) {
                $itemNoList[] = $item['item_no'];
            }
            
            // 创建溯源码记录
            $traceData = [
                'trace_code' => $traceCode,
                'active_report_id' => $activeReport['id'],
                'product_name' => $productName,
                'item_no' => json_encode($itemNoList), // 保存产品编号列表
                'process_name' => $processName,
                'worker_name' => $workerName,
                'auditor_name' => $auditorName,
                'remark' => '主动报工审核通过',
                'audit_time' => time(),
                'status' => 1,
                'createtime' => time(),
                'updatetime' => time()
            ];
            
            $traceId = Db::name('scanwork_trace_codes')->insertGetId($traceData);
            
            if ($traceId) {
                // 生成溯源码二维码图片
                $this->generateQrCodeImage($traceCode);
            }
            
        } catch (Exception $e) {
            // 静默处理异常，不影响审核流程
            \think\Log::error('创建主动报工溯源码异常 - 主动报工ID: ' . $activeReport['id'] . ', 错误: ' . $e->getMessage());
        }
    }
    
    /**
     * 生成溯源码二维码图片
     */
    private function generateQrCodeImage($traceCode)
    {
        try {
            $dateDir = date('Ymd');
            $qrDir = ROOT_PATH . 'public' . DS . 'uploads' . DS . 'trace_qrcode' . DS . $dateDir;
            if (!is_dir($qrDir)) {
                mkdir($qrDir, 0755, true);
            }
            
            $filename = "trace_{$traceCode}_" . time() . ".png";
            $filepath = $qrDir . DS . $filename;
            
            // 使用在线API生成二维码
            $apiUrl = 'https://api.qrserver.com/v1/create-qr-code/';
            $params = [
                'size' => '300x300',
                'data' => ConfigModel::getTraceUrl($traceCode),
                'format' => 'png'
            ];
            
            $url = $apiUrl . '?' . http_build_query($params);
            $qrCodeImage = file_get_contents($url);
            
            if ($qrCodeImage !== false) {
                file_put_contents($filepath, $qrCodeImage);
            }
            
        } catch (Exception $e) {
            \think\Log::error('溯源码二维码生成失败: ' . $e->getMessage());
        }
    }

    // ==================== 用户管理 ====================
    
    /**
     * 获取用户列表
     */
    public function getUserList()
    {
        try {
            $page = $this->request->get('page', 1);
            $limit = $this->request->get('limit', 20);
            $keyword = $this->request->get('keyword', '');
            
            $where = [];
            
            // 分页查询
            $offset = ($page - 1) * $limit;
            $query = Db::name('user');
            
            // 搜索条件
            if ($keyword) {
                $query->where(function($query) use ($keyword) {
                    $query->where('username', 'like', "%{$keyword}%")
                          ->whereOr('nickname', 'like', "%{$keyword}%")
                          ->whereOr('mobile', 'like', "%{$keyword}%");
                });
            }
            
            $userList = $query->field('id,username,nickname,mobile,avatar,status,createtime,logintime')
                ->order('id DESC')
                ->limit($offset, $limit)
                ->select();
            
            // 重新构建查询用于统计总数
            $countQuery = Db::name('user');
            if ($keyword) {
                $countQuery->where(function($query) use ($keyword) {
                    $query->where('username', 'like', "%{$keyword}%")
                          ->whereOr('nickname', 'like', "%{$keyword}%")
                          ->whereOr('mobile', 'like', "%{$keyword}%");
                });
            }
            $total = $countQuery->count();
            
            $this->success('获取成功', [
                'list' => $userList,
                'total' => $total,
                'page' => $page,
                'limit' => $limit
            ]);
            
        } catch (Exception $e) {
            $this->error('获取用户列表失败：' . $e->getMessage());
        }
    }
    
    /**
     * 更新用户信息
     */
    public function updateUser()
    {
        try {
            $data = $this->request->post();
            
            if (empty($data['id'])) {
                $this->error('用户ID不能为空');
            }
            
            $userId = intval($data['id']);
            $updateData = [];
            
            // 可更新的字段
            if (isset($data['nickname'])) {
                $updateData['nickname'] = $data['nickname'];
            }
            if (isset($data['mobile'])) {
                $updateData['mobile'] = $data['mobile'];
            }
            if (isset($data['status'])) {
                $updateData['status'] = $data['status'];
            }
            
            if (empty($updateData)) {
                $this->error('没有可更新的数据');
            }
            
            $updateData['updatetime'] = time();
            
            $result = Db::name('user')->where('id', $userId)->update($updateData);
            
            if ($result !== false) {
                $this->success('更新成功');
            } else {
                $this->error('更新失败');
            }
            
        } catch (Exception $e) {
            $this->error('更新用户失败：' . $e->getMessage());
        }
    }
    
    /**
     * 删除用户
     */
    public function deleteUser()
    {
        try {
            $userId = $this->request->post('id');
            
            if (empty($userId)) {
                $this->error('用户ID不能为空');
            }
            
            $userId = intval($userId);
            
            // 检查用户是否存在
            $user = Db::name('user')->where('id', $userId)->find();
            if (!$user) {
                $this->error('用户不存在');
            }
            
            // 检查是否为管理员用户
            if ($user['username'] === 'admin') {
                $this->error('不能删除管理员用户');
            }
            
            // 检查用户是否有关联数据
            $orderCount = Db::name('scanwork_order')->where('user_id', $userId)->count();
            if ($orderCount > 0) {
                $this->error('该用户有关联的订单数据，无法删除');
            }
            
            $result = Db::name('user')->where('id', $userId)->delete();
            
            if ($result) {
                $this->success('删除成功');
            } else {
                $this->error('删除失败');
            }
            
        } catch (Exception $e) {
            $this->error('删除用户失败：' . $e->getMessage());
        }
    }
    
    /**
     * 修改用户密码
     */
    public function changeUserPassword()
    {
        try {
            $data = $this->request->post();
            
            if (empty($data['id'])) {
                $this->error('用户ID不能为空');
            }
            
            if (empty($data['password'])) {
                $this->error('新密码不能为空');
            }
            
            $userId = intval($data['id']);
            $newPassword = $data['password'];
            
            // 检查用户是否存在
            $user = Db::name('user')->where('id', $userId)->find();
            if (!$user) {
                $this->error('用户不存在');
            }
            
            // 生成新的密码盐和密码
            $salt = $this->random_string(6);
            $hashedPassword = md5(md5($newPassword) . $salt);
            
            $updateData = [
                'password' => $hashedPassword,
                'salt' => $salt,
                'updatetime' => time()
            ];
            
            $result = Db::name('user')->where('id', $userId)->update($updateData);
            
            if ($result !== false) {
                $this->success('密码修改成功');
            } else {
                $this->error('密码修改失败');
            }
            
        } catch (Exception $e) {
            $this->error('修改密码失败：' . $e->getMessage());
        }
    }

    /**
     * 获取生产计划列表
     */
    public function getProductionPlans()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $status = $this->request->get('status', '');
        $orderId = $this->request->get('order_id', '');
        
        $where = [];
        if ($status !== '') {
            $where['status'] = $status;
        }
        if ($orderId) {
            $where['order_id'] = $orderId;
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $list = $model->with(['order', 'product', 'model', 'customer'])
                ->where($where)
                ->order('createtime desc')
                ->paginate($limit, false, ['page' => $page]);
            
            $rows = [];
            foreach ($list as $item) {
                $row = $item->toArray();
                $stats = $item->getPlanStats();
                $row['completion_rate'] = $stats['completion_rate'];
                $row['remaining_quantity'] = $stats['remaining_quantity'];
                $row['allocation_count'] = $stats['allocation_count'];
                $row['actual_quantity'] = $stats['total_reported'];
                $rows[] = $row;
            }
            
            $this->success('获取成功', [
                'total' => $list->total(),
                'rows' => $rows
            ]);
        } catch (Exception $e) {
            $this->error('获取生产计划列表失败：' . $e->getMessage());
        }
    }

    /**
     * 创建生产计划
     */
    public function createProductionPlan()
    {
        $data = $this->request->post();
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            
            // 生成计划编码
            if (empty($data['plan_code'])) {
                $data['plan_code'] = $this->generatePlanCode();
            }
            
            // 生成计划名称
            if (empty($data['plan_name'])) {
                $data['plan_name'] = $data['product_name'] . ' - ' . $data['product_model'] . ' - 生产计划';
            }
            
            // 处理时间字段
            if (!empty($data['planned_start_time'])) {
                $data['planned_start_time'] = strtotime($data['planned_start_time']);
            }
            if (!empty($data['planned_end_time'])) {
                $data['planned_end_time'] = strtotime($data['planned_end_time']);
            }
            
            // 字段映射：planned_quantity -> total_quantity
            if (isset($data['planned_quantity'])) {
                $data['total_quantity'] = (int)$data['planned_quantity'];
                unset($data['planned_quantity']);
            }
            
            // 字段映射：description -> remark
            if (isset($data['description'])) {
                $data['remark'] = $data['description'];
                unset($data['description']);
            }
            
            // 根据产品名称和型号名称获取对应的ID
            if (!empty($data['product_name']) && !empty($data['product_model'])) {
                $product = \app\admin\model\scanwork\Product::where('name', $data['product_name'])->find();
                if ($product) {
                    $data['product_id'] = $product->id;
                }
                
                $productModel = \app\admin\model\scanwork\ProductModel::where('name', $data['product_model'])->find();
                if ($productModel) {
                    $data['model_id'] = $productModel->id;
                }
            }
            
            // 添加默认的工序序列和关键节点
            $data['process_sequence'] = json_encode([]);
            $data['key_milestones'] = json_encode([]);
            $data['createtime'] = time();
            $data['updatetime'] = time();
            
            $plan = $model->create($data);
            
            if ($plan) {
                // 暂时跳过工序序列生成，先让基本功能工作
                $this->success('创建成功');
            } else {
                $this->error('创建失败');
            }
        } catch (Exception $e) {
            $this->error('创建生产计划失败：' . $e->getMessage());
        }
    }

    /**
     * 生成计划编码
     */
    private function generatePlanCode()
    {
        $prefix = 'JH-' . date('Y') . '-';
        $model = new \app\admin\model\scanwork\ProductionPlan;
        $lastCode = $model->where('plan_code', 'like', $prefix . '%')
            ->order('plan_code desc')
            ->value('plan_code');
        
        if ($lastCode) {
            $lastNumber = intval(substr($lastCode, -3));
            $newNumber = $lastNumber + 1;
        } else {
            $newNumber = 1;
        }
        
        return $prefix . str_pad($newNumber, 3, '0', STR_PAD_LEFT);
    }

    /**
     * 更新生产计划
     */
    public function updateProductionPlan()
    {
        $planId = $this->request->post('id');
        $data = $this->request->post();
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            // 处理时间字段
            if (!empty($data['planned_start_time'])) {
                $data['planned_start_time'] = strtotime($data['planned_start_time']);
            }
            if (!empty($data['planned_end_time'])) {
                $data['planned_end_time'] = strtotime($data['planned_end_time']);
            }
            if (!empty($data['actual_start_time'])) {
                $data['actual_start_time'] = strtotime($data['actual_start_time']);
            }
            if (!empty($data['actual_end_time'])) {
                $data['actual_end_time'] = strtotime($data['actual_end_time']);
            }
            
            // 字段映射：planned_quantity -> total_quantity
            if (isset($data['planned_quantity'])) {
                $data['total_quantity'] = (int)$data['planned_quantity'];
                unset($data['planned_quantity']);
            }
            
            $result = $plan->allowField(true)->save($data);
            
            if ($result !== false) {
                $this->success('更新成功');
            } else {
                $this->error('更新失败');
            }
        } catch (Exception $e) {
            $this->error('更新生产计划失败：' . $e->getMessage());
        }
    }

    /**
     * 删除生产计划
     */
    public function deleteProductionPlan()
    {
        $planId = $this->request->post('id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            // 检查是否有关联的分工分配
            $allocationCount = \app\admin\model\scanwork\Allocation::where('plan_id', $planId)->count();
            if ($allocationCount > 0) {
                $this->error("生产计划【{$plan->plan_name}】下还有{$allocationCount}个分工分配，请先删除相关分工");
            }
            
            $result = $plan->delete();
            
            if ($result) {
                $this->success('删除成功');
            } else {
                $this->error('删除失败');
            }
        } catch (Exception $e) {
            $this->error('删除生产计划失败：' . $e->getMessage());
        }
    }

    /**
     * 获取生产计划详情
     */
    public function getProductionPlanDetail()
    {
        $planId = $this->request->get('id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            // 获取计划统计信息
            $stats = $plan->getPlanStats();
            
            // 获取分工分配详情
            $allocations = \app\admin\model\scanwork\Allocation::with(['model.product', 'process', 'user'])
                ->where('plan_id', $planId)
                ->select();
            
            $planData = $plan->toArray();
            $planData['stats'] = $stats;
            $planData['allocations'] = $allocations;
            $planData['process_sequence'] = $plan->process_sequence;
            $planData['key_milestones'] = $plan->key_milestones;
            
            $this->success('获取成功', $planData);
        } catch (Exception $e) {
            $this->error('获取生产计划详情失败：' . $e->getMessage());
        }
    }

    /**
     * 获取生产计划的分工分配
     */
    public function getProductionPlanAllocations()
    {
        $planId = $this->request->get('plan_id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            // 获取关联的分工分配
            $allocations = \app\admin\model\scanwork\Allocation::with(['process', 'user'])
                ->where('plan_id', $plan->id)
                ->select();
            
            $this->success('获取成功', [
                'plan' => $plan,
                'allocations' => $allocations
            ]);
        } catch (Exception $e) {
            $this->error('获取分工分配失败：' . $e->getMessage());
        }
    }

    /**
     * 工序分配管理
     */
    public function allocateProductionPlan()
    {
        $planId = $this->request->get('plan_id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            // 获取可用的工序
            $processList = \app\admin\model\scanwork\Process::where('status', 1)
                ->column('name', 'id');
            
            // 获取可用的工人
            $userList = \app\common\model\User::where('status', 'normal')
                ->column('nickname', 'id');
            
            // 获取每个工序的分配情况
            // 分配记录通过plan_id精确关联到具体的生产计划
            $processAllocations = \app\admin\model\scanwork\Allocation::where('plan_id', $planId)
                ->field('process_id, SUM(quantity) as allocated_quantity')
                ->group('process_id')
                ->select();
            
            // 构建工序分配数据
            $processAllocationData = [];
            foreach ($processAllocations as $allocation) {
                $processAllocationData[$allocation->process_id] = $allocation->allocated_quantity;
            }
            
            // 为每个工序添加分配信息
            $processListWithAllocation = [];
            foreach ($processList as $processId => $processName) {
                $allocated = isset($processAllocationData[$processId]) ? $processAllocationData[$processId] : 0;
                $remaining = $plan->total_quantity - $allocated;
                
                $processListWithAllocation[$processId] = [
                    'id' => $processId,
                    'name' => $processName,
                    'total_quantity' => $plan->total_quantity,
                    'allocated_quantity' => $allocated,
                    'remaining_quantity' => $remaining
                ];
            }
            
            $this->success('获取成功', [
                'plan' => $plan,
                'processList' => $processList,
                'userList' => $userList,
                'processListWithAllocation' => $processListWithAllocation
            ]);
        } catch (Exception $e) {
            $this->error('获取分配信息失败：' . $e->getMessage());
        }
    }

    /**
     * 批量分配工序
     */
    public function batchAllocateProductionPlan()
    {
        $planId = $this->request->get('plan_id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            // 获取可用的工序
            $processList = \app\admin\model\scanwork\Process::where('status', 1)
                ->column('name', 'id');
            
            // 获取可用的工人
            $userList = \app\common\model\User::where('status', 'normal')
                ->column('nickname', 'id');
            
            $this->success('获取成功', [
                'plan' => $plan,
                'processList' => $processList,
                'userList' => $userList
            ]);
        } catch (Exception $e) {
            $this->error('获取分配信息失败：' . $e->getMessage());
        }
    }

    /**
     * 保存批量分配
     */
    public function saveBatchAllocateProductionPlan()
    {
        $params = $this->request->post();
        
        $planId = $params['plan_id'];
        $allocations = $params['allocations'];
        
        if (empty($planId) || empty($allocations)) {
            $this->error('参数不完整');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            $successCount = 0;
            $errors = [];
            
            foreach ($allocations as $allocation) {
                if (empty($allocation['process_id']) || empty($allocation['user_id']) || empty($allocation['quantity'])) {
                    continue;
                }
                
                // 生成产品编号前缀
                $order = \app\admin\model\scanwork\Order::get($plan->order_id);
                $model = \app\admin\model\scanwork\ProductModel::get($plan->model_id);
                $process = \app\admin\model\scanwork\Process::get($allocation['process_id']);
                $itemPrefix = '';
                if ($order && $model && $process) {
                    $itemPrefix = $order->order_no . '-' . $model->name . '-' . $process->name . '-';
                }
                
                $data = [
                    'plan_id' => $planId,
                    'order_id' => $plan->order_id,
                    'model_id' => $plan->model_id,
                    'process_id' => $allocation['process_id'],
                    'user_id' => $allocation['user_id'],
                    'quantity' => $allocation['quantity'],
                    'work_type' => 'piece',
                    'type' => 'piece',
                    'status' => 0,
                    'item_prefix' => $itemPrefix,
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                try {
                    $allocationModel = \app\admin\model\scanwork\Allocation::create($data);
                    
                    // 生成产品编号（仅计件工作）
                    if ($allocationModel && $allocationModel->id && $allocation['quantity'] > 0 && $itemPrefix) {
                        $itemNos = \app\admin\model\scanwork\ProductItem::generateItemNos($allocationModel->id, $itemPrefix, $allocation['quantity']);
                        $createResult = \app\admin\model\scanwork\ProductItem::createItems($allocationModel->id, $itemNos);
                        if (!$createResult) {
                            throw new Exception('产品编号生成失败');
                        }
                    }
                    
                    $successCount++;
                } catch (Exception $e) {
                    $errors[] = $e->getMessage();
                }
            }
            
            if ($successCount == 0) {
                $this->error('没有有效的分配数据');
            }
            
            if (!empty($errors)) {
                $this->error('部分分配保存失败：' . implode('; ', $errors));
            }
            
            $this->success('批量分配成功，共保存' . $successCount . '条记录');
        } catch (Exception $e) {
            $this->error('批量分配失败：' . $e->getMessage());
        }
    }

    /**
     * 开始生产计划
     */
    public function startProductionPlan()
    {
        $planId = $this->request->post('id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            $plan->start();
            $this->success('计划已开始');
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 暂停生产计划
     */
    public function pauseProductionPlan()
    {
        $planId = $this->request->post('id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            $plan->pause();
            $this->success('计划已暂停');
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 恢复生产计划
     */
    public function resumeProductionPlan()
    {
        $planId = $this->request->post('id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            $plan->resume();
            $this->success('计划已恢复');
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 完成生产计划
     */
    public function completeProductionPlan()
    {
        $planId = $this->request->post('id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            $plan->complete();
            $this->success('计划已完成');
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 更新生产计划进度
     */
    public function updateProductionPlanProgress()
    {
        $planId = $this->request->post('id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            $plan->updateProgress();
            $this->success('进度更新成功');
        } catch (Exception $e) {
            $this->error('更新失败：' . $e->getMessage());
        }
    }

    /**
     * 获取生产计划统计信息
     */
    public function getProductionPlanStats()
    {
        $planId = $this->request->get('id');
        
        if (!$planId) {
            $this->error('生产计划ID不能为空');
        }
        
        try {
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plan = $model->get($planId);
            
            if (!$plan) {
                $this->error('生产计划不存在');
            }
            
            $stats = $plan->getPlanStats();
            $this->success('获取成功', $stats);
        } catch (Exception $e) {
            $this->error('获取统计信息失败：' . $e->getMessage());
        }
    }

    /**
     * 获取生产进度统计
     */
    public function getProductionPlanProgress()
    {
        try {
            // 获取筛选参数
            $orderId = $this->request->get('order_id', '');
            $planId = $this->request->get('plan_id', '');
            $processId = $this->request->get('process_id', '');
            $userId = $this->request->get('user_id', '');
            $startTime = $this->request->get('start_time', '');
            $endTime = $this->request->get('end_time', '');
            
            // 调试信息
            \think\Log::info('筛选参数 - orderId: ' . $orderId . ', planId: ' . $planId . ', processId: ' . $processId . ', userId: ' . $userId . ', startTime: ' . $startTime . ', endTime: ' . $endTime);
            
            // 构建查询条件
            $where = [];
            if ($orderId) {
                $where['order_id'] = $orderId;
            }
            if ($planId) {
                $where['id'] = $planId;
            }
            
            // 获取生产计划，包含订单的完整信息
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $plans = $model->where($where)->with(['order'])->select();
            
            // 如果有工序或员工筛选，需要进一步过滤
            if ($processId || $userId || $startTime || $endTime) {
                $filteredPlans = [];
                
                foreach ($plans as $plan) {
                    $shouldInclude = true;
                    
                    // 检查工序筛选
                    if ($processId) {
                        $hasProcess = \app\admin\model\scanwork\Allocation::where('order_id', $plan->order_id)
                            ->where('model_id', $plan->model_id)
                            ->where('process_id', $processId)
                            ->count() > 0;
                        if (!$hasProcess) {
                            $shouldInclude = false;
                        }
                    }
                    
                    // 检查员工筛选
                    if ($userId && $shouldInclude) {
                        $hasUser = \app\admin\model\scanwork\Allocation::where('order_id', $plan->order_id)
                            ->where('model_id', $plan->model_id)
                            ->where('user_id', $userId)
                            ->count() > 0;
                        if (!$hasUser) {
                            $shouldInclude = false;
                        }
                    }
                    
                    // 检查日期筛选
                    if (($startTime || $endTime) && $shouldInclude) {
                        $planTime = $plan->createtime;
                        if ($startTime && $planTime < $startTime) {
                            $shouldInclude = false;
                        }
                        if ($endTime && $planTime > $endTime) {
                            $shouldInclude = false;
                        }
                    }
                    
                    if ($shouldInclude) {
                        $filteredPlans[] = $plan;
                    }
                }
                
                $plans = $filteredPlans;
            }
            
            // 整体统计
            $overallStats = [
                'total_orders' => 0,
                'total_plans' => 0,
                'total_allocations' => 0,
                'total_reports' => 0,
                'total_quantity' => 0,
                'completed_quantity' => 0,
                'overall_completion_rate' => 0
            ];
            
            $processedOrders = [];
            
            foreach ($plans as $plan) {
                $overallStats['total_plans']++;
                $overallStats['total_quantity'] += $plan->total_quantity;
                
                // 计算该计划的已完成数量和小工单数
                $planCompletedQuantity = 0;
                $planAllocations = \app\admin\model\scanwork\Allocation::where('order_id', $plan->order_id)
                    ->where('model_id', $plan->model_id)
                    ->select();
                
                // 统计小工单数
                $overallStats['total_allocations'] += count($planAllocations);
                
                foreach ($planAllocations as $allocation) {
                    // 统计所有已提交的报工记录（包括待审核和已确认的）
                    $reports = \app\admin\model\scanwork\Report::where('allocation_id', $allocation->id)
                        ->whereIn('status', [0, 1]) // 0: 待审核, 1: 已确认
                        ->sum('quantity');
                    $planCompletedQuantity += $reports ?: 0;
                }
                $overallStats['completed_quantity'] += $planCompletedQuantity;
                
                // 按订单统计
                if ($plan->order) {
                    $orderId = $plan->order->id;
                    if (!isset($processedOrders[$orderId])) {
                        $processedOrders[$orderId] = true;
                        $overallStats['total_orders']++;
                    }
                }
            }
            
            if ($overallStats['total_quantity'] > 0) {
                $overallStats['overall_completion_rate'] = round(($overallStats['completed_quantity'] / $overallStats['total_quantity']) * 100, 1);
            }
            
            // 为每个计划计算完成数量和完成率
            $processedPlans = [];
            foreach ($plans as $plan) {
                $planData = $plan->toArray();
                
                // 计算该计划的已完成数量
                $planCompletedQuantity = 0;
                $planAllocations = \app\admin\model\scanwork\Allocation::where('order_id', $plan->order_id)
                    ->where('model_id', $plan->model_id)
                    ->select();
                
                foreach ($planAllocations as $allocation) {
                    $reports = \app\admin\model\scanwork\Report::where('allocation_id', $allocation->id)
                        ->whereIn('status', [0, 1]) // 0: 待审核, 1: 已确认
                        ->sum('quantity');
                    $planCompletedQuantity += $reports ?: 0;
                }
                
                // 计算完成率
                $planCompletionRate = 0;
                if ($plan->total_quantity > 0) {
                    $planCompletionRate = round(($planCompletedQuantity / $plan->total_quantity) * 100, 1);
                }
                
                // 添加计算后的字段
                $planData['actual_quantity'] = $planCompletedQuantity;
                $planData['completion_rate'] = $planCompletionRate;
                $planData['allocation_count'] = count($planAllocations);
                
                // 确保订单信息正确显示
                if (isset($planData['order']) && $planData['order']) {
                    $planData['order_name'] = $planData['order']['order_name'] ?? '-';
                    $planData['order_no'] = $planData['order']['order_no'] ?? '-';
                    $planData['customer_name'] = $planData['order']['customer_name'] ?? '-';
                    
                    // 调试信息
                    \think\Log::info('订单信息调试 - Plan ID: ' . $plan->id . ', Order Name: ' . $planData['order_name'] . ', Order No: ' . $planData['order_no']);
                } else {
                    $planData['order_name'] = '-';
                    $planData['order_no'] = '-';
                    $planData['customer_name'] = '-';
                    \think\Log::info('订单信息调试 - Plan ID: ' . $plan->id . ', 订单数据为空');
                }
                
                $processedPlans[] = $planData;
            }
            
            // 如果指定了单个计划ID，返回详细的分配和工序信息
            $detailedData = null;
            if ($planId && count($plans) == 1) {
                $plan = $plans[0];
                $detailedData = $this->getPlanDetailedProgress($plan);
            }
            
            // 计算工序统计信息
            $processStats = $this->getProcessStats();
            
            // 计算员工统计信息
            $employeeStats = $this->getEmployeeStats();
            
            $this->success('获取成功', [
                'overallStats' => $overallStats,
                'plans' => $processedPlans,
                'detailedData' => $detailedData,
                'processStats' => $processStats,
                'employeeStats' => $employeeStats
            ]);
        } catch (Exception $e) {
            $this->error('获取生产进度失败：' . $e->getMessage());
        }
    }

    /**
     * 获取单个计划的详细进度信息
     */
    private function getPlanDetailedProgress($plan)
    {
        try {
            // 获取该计划的所有分配任务
            $allocations = \app\admin\model\scanwork\Allocation::where('order_id', $plan->order_id)
                ->where('model_id', $plan->model_id)
                ->with(['process', 'user'])
                ->select();
            
            $processStats = [];
            $userStats = [];
            $totalAllocated = 0;
            $totalReported = 0;
            
            foreach ($allocations as $allocation) {
                // 工序统计
                $processId = $allocation->process_id;
                if (!isset($processStats[$processId])) {
                    $processStats[$processId] = [
                        'process_id' => $processId,
                        'process_name' => $allocation->process ? $allocation->process->name : '未知工序',
                        'total_allocated' => 0,
                        'total_reported' => 0,
                        'allocation_count' => 0,
                        'user_count' => 0,
                        'users' => []
                    ];
                }
                
                $processStats[$processId]['total_allocated'] += $allocation->quantity;
                $processStats[$processId]['allocation_count']++;
                $totalAllocated += $allocation->quantity;
                
                // 员工统计
                $userId = $allocation->user_id;
                if (!isset($userStats[$userId])) {
                    $userStats[$userId] = [
                        'user_id' => $userId,
                        'user_name' => $allocation->user ? $allocation->user->nickname : '未知员工',
                        'total_allocated' => 0,
                        'total_reported' => 0,
                        'allocation_count' => 0,
                        'processes' => []
                    ];
                }
                
                $userStats[$userId]['total_allocated'] += $allocation->quantity;
                $userStats[$userId]['allocation_count']++;
                
                // 获取报工记录
                $reports = \app\admin\model\scanwork\Report::where('allocation_id', $allocation->id)
                    ->whereIn('status', [0, 1])
                    ->sum('quantity');
                $reportedQuantity = $reports ?: 0;
                
                $processStats[$processId]['total_reported'] += $reportedQuantity;
                $userStats[$userId]['total_reported'] += $reportedQuantity;
                $totalReported += $reportedQuantity;
                
                // 记录工序-员工关系
                if (!in_array($userId, $processStats[$processId]['users'])) {
                    $processStats[$processId]['users'][] = $userId;
                    $processStats[$processId]['user_count']++;
                }
                
                // 记录员工-工序关系
                if (!in_array($processId, $userStats[$userId]['processes'])) {
                    $userStats[$userId]['processes'][] = $processId;
                }
            }
            
            // 计算完成率
            foreach ($processStats as &$process) {
                $process['completion_rate'] = $process['total_allocated'] > 0 ? 
                    round(($process['total_reported'] / $process['total_allocated']) * 100, 1) : 0;
            }
            
            foreach ($userStats as &$user) {
                $user['completion_rate'] = $user['total_allocated'] > 0 ? 
                    round(($user['total_reported'] / $user['total_allocated']) * 100, 1) : 0;
            }
            
            return [
                'plan_info' => [
                    'id' => $plan->id,
                    'plan_name' => $plan->plan_name,
                    'order_name' => $plan->order ? $plan->order->order_name : '-',
                    'product_name' => $plan->product_name,
                    'model_name' => $plan->product_model,
                    'total_quantity' => $plan->total_quantity,
                    'total_allocated' => $totalAllocated,
                    'total_reported' => $totalReported,
                    'overall_completion_rate' => $totalAllocated > 0 ? round(($totalReported / $totalAllocated) * 100, 1) : 0
                ],
                'process_stats' => array_values($processStats),
                'user_stats' => array_values($userStats),
                'allocation_count' => count($allocations),
                'process_count' => count($processStats),
                'user_count' => count($userStats)
            ];
            
        } catch (Exception $e) {
            \think\Log::error('获取详细进度失败: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * 基于订单生成生产计划
     */
    public function generateProductionPlanFromOrder()
    {
        $orderId = $this->request->post('order_id');
        $modelIds = $this->request->post('model_ids', []);
        
        if (!$orderId) {
            $this->error('请选择订单');
        }
        
        // 处理model_ids，可能是JSON字符串或数组
        if (is_string($modelIds)) {
            $modelIds = json_decode($modelIds, true);
        }
        
        // 确保model_ids是数组格式
        if (!is_array($modelIds)) {
            $modelIds = [$modelIds];
        }
        
        if (empty($modelIds)) {
            $this->error('请选择要生成计划的产品型号');
        }
        
        try {
            $order = \app\admin\model\scanwork\Order::get($orderId);
            if (!$order) {
                $this->error('订单不存在');
            }
            
            // 检查选中的产品型号是否已有生产计划
            $model = new \app\admin\model\scanwork\ProductionPlan;
            $existingPlans = $model->where('order_id', $orderId)
                ->whereIn('model_id', $modelIds)
                ->select();
            
            if (count($existingPlans) > 0) {
                $existingModelNames = [];
                foreach ($existingPlans as $plan) {
                    $existingModelNames[] = $plan->product_model;
                }
                $this->error('以下产品型号已存在生产计划：' . implode('、', $existingModelNames));
            }
            
            // 获取选中的订单型号
            $orderModels = \app\admin\model\scanwork\OrderModel::with(['model.product'])
                ->where('order_id', $orderId)
                ->whereIn('model_id', $modelIds)
                ->select();
            
            $createdPlans = [];
            foreach ($orderModels as $orderModel) {
                // 通过客户名称查找客户ID
                $customerId = null;
                if (!empty($order->customer_name)) {
                    $customer = \app\admin\model\scanwork\Customer::where('customer_name', $order->customer_name)->find();
                    if ($customer) {
                        $customerId = $customer->id;
                    }
                }
                
                $planData = [
                    'plan_code' => $this->generatePlanCode(),
                    'order_id' => $orderId,
                    'product_id' => $orderModel->model->product_id,
                    'model_id' => $orderModel->model_id,
                    'customer_id' => $customerId,
                    'plan_name' => $order->order_no . ' - ' . $orderModel->model->product->name . ' - ' . $orderModel->model->name,
                    'product_name' => $orderModel->model->product->name,
                    'product_model' => $orderModel->model->name,
                    'total_quantity' => $orderModel->quantity,
                    'planned_start_time' => time(),
                    'planned_end_time' => $order->delivery_time ?: (time() + 7 * 86400),
                    'status' => 0,
                    'createtime' => time()
                ];
                
                $plan = $model->create($planData);
                
                // 生成默认工序顺序和关键节点
                try {
                    // 确保plan对象有正确的product_id
                    $plan->product_id = $planData['product_id'];
                    $processSequence = $plan->generateDefaultProcessSequence();
                    $plan->save([
                        'process_sequence' => json_encode($processSequence),
                        'key_milestones' => json_encode([]) // 暂时设为空，避免循环依赖
                    ]);
                } catch (Exception $e) {
                    // 如果生成失败，使用默认值
                    $plan->save([
                        'process_sequence' => json_encode([]),
                        'key_milestones' => json_encode([])
                    ]);
                }
                
                $createdPlans[] = $plan;
            }
            
            $this->success('生产计划生成成功，共生成' . count($createdPlans) . '个计划');
        } catch (Exception $e) {
            $this->error('生成失败：' . $e->getMessage());
        }
    }

    /**
     * 根据订单获取产品和型号信息
     */
    public function getOrderProducts()
    {
        $orderId = $this->request->get('order_id');
        
        if (!$orderId) {
            $this->error('订单ID不能为空');
        }
        
        try {
            $order = \app\admin\model\scanwork\Order::with(['orderModels.model.product'])->find($orderId);
            if (!$order) {
                $this->error('订单不存在');
            }
            
            $products = [];
            foreach ($order->orderModels as $orderModel) {
                $model = $orderModel->model;
                $product = $model->product;
                
                $products[] = [
                    'product_id' => $product->id,
                    'product_name' => $product->name,
                    'model_id' => $orderModel->id, // 返回订单型号ID，而不是产品型号ID
                    'product_model_id' => $model->id, // 产品型号ID
                    'model_name' => $model->name,
                    'quantity' => $orderModel->quantity
                ];
            }
            
            $this->success('获取成功', $products);
        } catch (Exception $e) {
            $this->error('获取订单产品信息失败：' . $e->getMessage());
        }
    }

    /**
     * 获取产品可用数量
     */
    public function getProductAvailableQuantity()
    {
        $modelId = $this->request->get('model_id');
        $orderId = $this->request->get('order_id');
        
        if (!$modelId) {
            $this->error('型号ID不能为空');
        }
        
        if (!$orderId) {
            $this->error('订单ID不能为空');
        }
        
        try {
            // 参考分工模块的逻辑：首先尝试作为订单型号ID查找
            $orderModel = \app\admin\model\scanwork\OrderModel::where([
                'id' => $modelId,
                'order_id' => $orderId
            ])->find();
            
            if ($orderModel) {
                // 如果是订单型号ID，获取该记录的数量
                $totalQuantity = $orderModel->quantity;
                $actualModelId = $orderModel->model_id;
            } else {
                // 如果不是订单型号ID，作为产品型号ID查找
                $orderModel = \app\admin\model\scanwork\OrderModel::where([
                    'order_id' => $orderId,
                    'model_id' => $modelId
                ])->find();
                
                if (!$orderModel) {
                    $this->error('未找到该订单中该型号的信息');
                }
                
                $totalQuantity = $orderModel->quantity;
                $actualModelId = $modelId;
            }
            
            // 计算当前订单型号记录的已分配数量（通过分配记录）
            // 只计算通过生产计划关联的分配记录，确保精确匹配
            $allocatedQuantity = \think\Db::name('scanwork_allocation')
                ->alias('a')
                ->join('scanwork_production_plan p', 'a.plan_id = p.id')
                ->where('a.order_id', $orderId)
                ->where('a.model_id', $actualModelId)
                ->where('a.status', 'in', [0, 1, 2]) // 已分配、进行中、已完成
                ->where('p.order_model_id', $modelId) // 通过生产计划精确匹配订单型号ID
                ->sum('a.quantity');
            
            // 计算当前订单型号记录的主动报工数量（通过主动报工记录）
            $reportedQuantity = \think\Db::name('scanwork_active_report')
                ->where('order_id', $orderId)
                ->where('model_id', $actualModelId)
                ->where('status', 1) // 已确认的主动报工
                ->sum('quantity');
            
            // 计算当前订单型号记录的生产计划数量（通过生产计划记录）
            // 只计算order_model_id匹配的生产计划
            $plannedQuantity = \think\Db::name('scanwork_production_plan')
                ->where('order_id', $orderId)
                ->where('order_model_id', $modelId) // 精确匹配订单型号ID
                ->where('status', 'in', [0, 1, 2, 3]) // 草稿、进行中、已暂停、已完成
                ->sum('total_quantity');
            
            // 计算可用数量 = 总数量 - 已分配数量 - 主动报工数量 - 生产计划数量
            $availableQuantity = $totalQuantity - $allocatedQuantity - $reportedQuantity - $plannedQuantity;
            if ($availableQuantity < 0) {
                $availableQuantity = 0;
            }
            
            $result = [
                'total_quantity' => $totalQuantity,
                'allocated_quantity' => $allocatedQuantity ?: 0,
                'reported_quantity' => $reportedQuantity ?: 0,
                'planned_quantity' => $plannedQuantity ?: 0,
                'available_quantity' => $availableQuantity
            ];
            
            $this->success('获取成功', $result);
        } catch (Exception $e) {
            $this->error('获取产品可用数量失败：' . $e->getMessage());
        }
    }

    /**
     * 获取工序统计信息
     */
    private function getProcessStats()
    {
        try {
            // 获取所有工序
            $processes = \app\admin\model\scanwork\Process::where('status', 1)->select();
            $processStats = [];
            
            foreach ($processes as $process) {
                // 获取该工序的所有分配
                $allocations = \app\admin\model\scanwork\Allocation::where('process_id', $process->id)->select();
                
                $totalQuantity = 0;
                $completedQuantity = 0;
                $allocationCount = count($allocations);
                
                foreach ($allocations as $allocation) {
                    $totalQuantity += $allocation->quantity ?: 0;
                    $completedQuantity += $allocation->reported_quantity ?: 0;
                }
                
                $completionRate = 0;
                if ($totalQuantity > 0) {
                    $completionRate = round(($completedQuantity / $totalQuantity) * 100, 1);
                }
                
                $processStats[] = [
                    'process_id' => $process->id,
                    'process_name' => $process->name,
                    'allocation_count' => $allocationCount,
                    'total_quantity' => $totalQuantity,
                    'completed_quantity' => $completedQuantity,
                    'completion_rate' => $completionRate
                ];
            }
            
            // 按完成率排序
            usort($processStats, function($a, $b) {
                return $b['completion_rate'] - $a['completion_rate'];
            });
            
            return $processStats;
        } catch (Exception $e) {
            \think\Log::error('获取工序统计失败：' . $e->getMessage());
            return [];
        }
    }

    /**
     * 获取员工统计信息
     */
    private function getEmployeeStats()
    {
        try {
            // 获取所有员工
            $users = \app\common\model\User::where('status', 'normal')->select();
            $employeeStats = [];
            
            foreach ($users as $user) {
                // 获取该员工的所有分配
                $allocations = \app\admin\model\scanwork\Allocation::where('user_id', $user->id)->select();
                
                $totalQuantity = 0;
                $completedQuantity = 0;
                $allocationCount = count($allocations);
                
                foreach ($allocations as $allocation) {
                    $totalQuantity += $allocation->quantity ?: 0;
                    $completedQuantity += $allocation->reported_quantity ?: 0;
                }
                
                $completionRate = 0;
                if ($totalQuantity > 0) {
                    $completionRate = round(($completedQuantity / $totalQuantity) * 100, 1);
                }
                
                $employeeStats[] = [
                    'user_id' => $user->id,
                    'user_name' => $user->nickname ?: $user->username,
                    'allocation_count' => $allocationCount,
                    'total_quantity' => $totalQuantity,
                    'completed_quantity' => $completedQuantity,
                    'completion_rate' => $completionRate
                ];
            }
            
            // 按完成率排序
            usort($employeeStats, function($a, $b) {
                return $b['completion_rate'] - $a['completion_rate'];
            });
            
            return $employeeStats;
        } catch (Exception $e) {
            \think\Log::error('获取员工统计失败：' . $e->getMessage());
            return [];
        }
    }

    /**
     * 提交每日工作报工
     */
    public function submitDailyWorkReport()
    {
        try {
            // 获取基本参数
            $workDate = input('post.work_date');
            $remark = input('post.remark', '');
            $workItems = input('post.work_items', []);
            
            \think\Log::info('submitDailyWorkReport - 基本参数: work_date=' . $workDate . ', work_items_count=' . count($workItems));
            
            if (!$workDate) {
                $this->error('请选择工作日期');
            }
            
            if (empty($workItems) || !is_array($workItems)) {
                $this->error('请至少添加一个工作项目');
            }
            
            // 验证每个工作项目
            foreach ($workItems as $index => $item) {
                if (!isset($item['order_id']) || !isset($item['model_id']) || !isset($item['process_id'])) {
                    $this->error('工作项目' . ($index + 1) . '缺少必要参数');
                }
                
                if (!isset($item['quantity']) || $item['quantity'] <= 0) {
                    $this->error('工作项目' . ($index + 1) . '数量必须大于0');
                }
                
                if (!isset($item['work_hours']) || $item['work_hours'] <= 0) {
                    $this->error('工作项目' . ($index + 1) . '工作时长必须大于0');
                }
                
                if (!isset($item['work_description']) || trim($item['work_description']) === '') {
                    $this->error('工作项目' . ($index + 1) . '请填写工作内容描述');
                }
            }
            
            // 开始事务
            Db::startTrans();
            
            // 创建每日工作报工记录
            $dailyReportData = [
                'user_id' => $this->auth->id ?? 0,
                'work_date' => $workDate,
                'remark' => $remark,
                'status' => 0, // 0: 待审核, 1: 通过, 2: 拒绝
                'createtime' => time(),
                'updatetime' => time()
            ];
            
            $dailyReportId = Db::name('scanwork_daily_work_report')->insertGetId($dailyReportData);
            
            \think\Log::info('submitDailyWorkReport - 创建每日工作报工记录成功，ID: ' . $dailyReportId);
            
            // 处理每个工作项目
            foreach ($workItems as $index => $item) {
                // 创建工作项目记录
                $workItemData = [
                    'daily_report_id' => $dailyReportId,
                    'order_id' => $item['order_id'],
                    'model_id' => $item['model_id'],
                    'process_id' => $item['process_id'],
                    'quantity' => $item['quantity'],
                    'work_hours' => $item['work_hours'],
                    'work_description' => $item['work_description'],
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                $workItemId = Db::name('scanwork_daily_work_item')->insertGetId($workItemData);
                
                \think\Log::info('submitDailyWorkReport - 创建工作项目记录成功，ID: ' . $workItemId);
                
                // 处理工作图片
                if (isset($item['images']) && is_array($item['images']) && !empty($item['images'])) {
                    foreach ($item['images'] as $imageUrl) {
                        $imageData = [
                            'daily_report_id' => $dailyReportId,
                            'work_item_id' => $workItemId,
                            'image_url' => $imageUrl,
                            'image_type' => 1, // 1: 员工上传的图片
                            'createtime' => time()
                        ];
                        
                        Db::name('scanwork_daily_work_image')->insert($imageData);
                    }
                }
            }
            
            // 提交事务
            Db::commit();
            
            \think\Log::info('submitDailyWorkReport - 提交成功');
            $this->success('每日工作报工提交成功');
            
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            \think\Log::error('submitDailyWorkReport - 提交失败: ' . $e->getMessage());
            $this->error('提交失败：' . $e->getMessage());
        }
    }

    /**
     * 获取每日工作记录（管理端）
     */
    public function getDailyWorkRecords()
    {
        try {
            $page = input('get.page', 1);
            $pageSize = input('get.page_size', 10);
            $workDate = input('get.work_date', '');
            $status = input('get.status', '');
            $userId = input('get.user_id', '');
            
            $where = [];
            
            if ($workDate) {
                $where['work_date'] = $workDate;
            }
            
            if ($status !== '') {
                $where['status'] = $status;
            }
            
            if ($userId) {
                $where['user_id'] = $userId;
            }
            
            $offset = ($page - 1) * $pageSize;
            
            // 获取记录列表
            $records = Db::name('scanwork_daily_work_report')
                ->where($where)
                ->order('createtime desc')
                ->limit($offset, $pageSize)
                ->select();
            
            // 处理每条记录
            foreach ($records as &$record) {
                // 获取工作项目统计
                $workItems = Db::name('scanwork_daily_work_item')
                    ->where('daily_report_id', $record['id'])
                    ->select();
                
                $record['work_items_count'] = count($workItems);
                $record['total_quantity'] = array_sum(array_column($workItems, 'quantity'));
                $record['total_work_hours'] = array_sum(array_column($workItems, 'work_hours'));
                
                // 状态文本
                $statusMap = ['0' => '待审核', '1' => '通过', '2' => '拒绝'];
                $record['status_text'] = $statusMap[$record['status']] ?? '未知';
                
                // 格式化时间
                $record['createtime_text'] = date('Y-m-d H:i:s', $record['createtime']);
                
                // 获取用户信息
                if ($record['user_id']) {
                    $user = Db::name('user')->where('id', $record['user_id'])->find();
                    $record['user_name'] = $user ? ($user['nickname'] ?: $user['username']) : '未知用户';
                } else {
                    $record['user_name'] = '未知用户';
                }
            }
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => [
                    'list' => $records,
                    'total' => Db::name('scanwork_daily_work_report')->where($where)->count()
                ],
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getDailyWorkRecords - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 获取每日工作统计信息（管理端）
     */
    public function getDailyWorkStats()
    {
        try {
            $total = Db::name('scanwork_daily_work_report')->count();
            $pending = Db::name('scanwork_daily_work_report')->where('status', 0)->count();
            $approved = Db::name('scanwork_daily_work_report')->where('status', 1)->count();
            $rejected = Db::name('scanwork_daily_work_report')->where('status', 2)->count();
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => [
                    'total' => $total,
                    'pending' => $pending,
                    'approved' => $approved,
                    'rejected' => $rejected
                ],
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getDailyWorkStats - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 审核每日工作报工（管理端）
     */
    public function auditDailyWorkReport()
    {
        try {
            $id = input('post.id');
            $status = input('post.status');
            $auditReason = input('post.audit_reason', '');
            
            if (!$id || !in_array($status, [1, 2])) {
                return json([
                    'code' => 0,
                    'msg' => '参数错误',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            $updateData = [
                'status' => $status,
                'audit_reason' => $auditReason,
                'audit_time' => time(),
                'audit_user_id' => $this->auth->id ?? 0,
                'updatetime' => time()
            ];
            
            $result = Db::name('scanwork_daily_work_report')
                ->where('id', $id)
                ->update($updateData);
            
            if ($result) {
                return json([
                    'code' => 1,
                    'msg' => '审核成功',
                    'data' => null,
                    'time' => time()
                ]);
            } else {
                return json([
                    'code' => 0,
                    'msg' => '审核失败',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
        } catch (Exception $e) {
            \think\Log::error('auditDailyWorkReport - 审核失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '审核失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 获取简单用户列表（管理端）
     */
    public function getSimpleUserList()
    {
        try {
            $users = Db::name('user')
                ->field('id, nickname, username, mobile, group_id')
                ->where('status', 'normal')
                ->order('id desc')
                ->select();
            
            // 处理用户数据，优先使用nickname，如果没有则使用username
            foreach ($users as &$user) {
                $user['name'] = $user['nickname'] ?: $user['username'];
            }
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => $users,
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getSimpleUserList - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 获取质检标准列表
     */
    public function getQualityStandards()
    {
        try {
            $standards = Db::name('scanwork_quality_standard')
                ->alias('qs')
                ->join('fa_scanwork_process p', 'qs.process_id = p.id', 'LEFT')
                ->join('fa_scanwork_product pr', 'qs.product_id = pr.id', 'LEFT')
                ->field('qs.id, qs.name, qs.process_id, qs.product_id, qs.check_items, qs.tolerance_requirements, qs.status, qs.createtime, qs.updatetime, p.name as process_name, pr.name as product_name')
                ->where('qs.status', 1)
                ->order('qs.id desc')
                ->select();
            
            // 解析JSON字段
            foreach ($standards as &$standard) {
                $standard['check_items_array'] = json_decode($standard['check_items'], true);
                $standard['tolerance_requirements_array'] = json_decode($standard['tolerance_requirements'], true);
            }
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => $standards,
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getQualityStandards - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 获取质检记录列表
     */
    public function getQualityRecords()
    {
        try {
            $page = $this->request->param('page', 1);
            $limit = $this->request->param('limit', 20);
            $offset = ($page - 1) * $limit;
            
            $records = Db::name('scanwork_quality_record')
                ->alias('qr')
                ->join('fa_scanwork_report r', 'qr.report_id = r.id', 'LEFT')
                ->join('fa_scanwork_quality_standard qs', 'qr.standard_id = qs.id', 'LEFT')
                ->join('fa_user u', 'qr.quality_user_id = u.id', 'LEFT')
                ->field('qr.id, qr.report_id, qr.standard_id, qr.quality_user_id, qr.overall_result, qr.handle_method, qr.check_time, qr.remark, qr.createtime, r.report_code, qs.name as standard_name, u.nickname as quality_user_name, u.username as quality_user_username')
                ->order('qr.id desc')
                ->limit($offset, $limit)
                ->select();
            
            $total = Db::name('scanwork_quality_record')->count();
            
            // 处理用户名称
            foreach ($records as &$record) {
                $record['quality_user_name'] = $record['quality_user_name'] ?: $record['quality_user_username'];
                unset($record['quality_user_username']);
            }
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => [
                    'list' => $records,
                    'total' => $total,
                    'page' => $page,
                    'limit' => $limit
                ],
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getQualityRecords - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 获取待质检报工列表
     */
    public function getPendingQualityReports()
    {
        try {
            $page = $this->request->param('page', 1);
            $limit = $this->request->param('limit', 20);
            $offset = ($page - 1) * $limit;
            
            // 查询还没有质检记录的报工（参考PC端的pending方法）
            $reports = Db::name('scanwork_report')
                ->alias('r')
                ->join('fa_scanwork_allocation a', 'r.allocation_id = a.id', 'LEFT')
                ->join('fa_scanwork_process p', 'a.process_id = p.id', 'LEFT')
                ->join('fa_scanwork_model pm', 'a.model_id = pm.id', 'LEFT')
                ->join('fa_scanwork_order o', 'a.order_id = o.id', 'LEFT')
                ->join('fa_scanwork_production_plan pl', 'a.plan_id = pl.id', 'LEFT')
                ->join('fa_user u', 'r.user_id = u.id', 'LEFT')
                ->field('r.id, r.report_code, r.quantity, r.remark, r.createtime, 
                        a.quantity as allocation_quantity, 
                        p.name as process_name, 
                        pm.name as model_name, 
                        o.order_name,
                        pl.plan_code,
                        u.nickname as user_name, u.username as user_username')
                ->where('r.id', 'not in', function($query) {
                    $query->table('fa_scanwork_quality_record')->field('report_id');
                })
                ->order('r.id desc')
                ->limit($offset, $limit)
                ->select();
            
            $total = Db::name('scanwork_report')
                ->where('id', 'not in', function($query) {
                    $query->table('fa_scanwork_quality_record')->field('report_id');
                })
                ->count();
            
            // 处理用户名称和格式化时间
            foreach ($reports as &$report) {
                $report['user_name'] = $report['user_name'] ?: $report['user_username'];
                unset($report['user_username']);
                $report['createtime_text'] = date('Y-m-d H:i:s', $report['createtime']);
            }
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => [
                    'list' => $reports,
                    'total' => $total,
                    'page' => $page,
                    'limit' => $limit
                ],
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getPendingQualityReports - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 执行质检
     */
    public function executeQualityCheck()
    {
        try {
            $reportId = $this->request->param('report_id');
            $checkResults = $this->request->param('check_results');
            $handleMethod = $this->request->param('handle_method', 1);
            $remark = $this->request->param('remark', '');
            
            if (!$reportId || !$checkResults) {
                return json([
                    'code' => 0,
                    'msg' => '参数不完整',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            // 获取报工记录
            $report = Db::name('scanwork_report')
                ->alias('r')
                ->join('fa_scanwork_allocation a', 'r.allocation_id = a.id', 'LEFT')
                ->field('r.*, a.process_id')
                ->where('r.id', $reportId)
                ->find();
            
            if (!$report) {
                return json([
                    'code' => 0,
                    'msg' => '报工记录不存在',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            // 获取质检标准
            $standard = Db::name('scanwork_quality_standard')
                ->where('process_id', $report['process_id'])
                ->where('status', 1)
                ->find();
            
            if (!$standard) {
                $standard = Db::name('scanwork_quality_standard')
                    ->where('process_id', null)
                    ->where('product_id', null)
                    ->where('status', 1)
                    ->find();
            }
            
            if (!$standard) {
                return json([
                    'code' => 0,
                    'msg' => '未找到对应的质检标准',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            // 计算总体结果
            $overallResult = $this->calculateOverallResult($checkResults);
            
            Db::startTrans();
            try {
                // 创建质检记录
                $qualityRecord = [
                    'report_id' => $reportId,
                    'standard_id' => $standard['id'],
                    'quality_user_id' => $this->auth->id ?? 0,
                    'check_results' => json_encode($checkResults),
                    'overall_result' => $overallResult,
                    'handle_method' => $handleMethod,
                    'check_time' => time(),
                    'remark' => $remark,
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                // 如果有不合格项目，记录详细信息
                if ($overallResult == 2) {
                    $unqualifiedItems = $this->getUnqualifiedItems($checkResults);
                    $qualityRecord['unqualified_items'] = json_encode($unqualifiedItems);
                }
                
                $recordId = Db::name('scanwork_quality_record')->insertGetId($qualityRecord);
                
                // 更新报工状态 - 质检是审核流程的一部分
                $updateData = [
                    'quality_result' => $overallResult,
                    'quality_remark' => $remark,
                    'updatetime' => time()
                ];
                
                if ($overallResult == 1) { // 质检合格
                    $updateData['status'] = 0; // 待审核（质检通过，进入审核阶段）
                } elseif ($overallResult == 2) { // 质检不合格
                    if ($handleMethod == 1) { // 返工
                        $updateData['status'] = -3; // 返工中
                    } elseif ($handleMethod == 2) { // 报废
                        $updateData['status'] = 2; // 已拒绝（质检失败，报工数据失效）
                    } elseif ($handleMethod == 3) { // 让步接收
                        $updateData['status'] = 0; // 待审核（让步接收，仍需审核）
                    }
                } elseif ($overallResult == 3) { // 让步接收
                    $updateData['status'] = 0; // 待审核（让步接收，仍需审核）
                }
                
                Db::name('scanwork_report')->where('id', $reportId)->update($updateData);
                
                Db::commit();
                
                return json([
                    'code' => 1,
                    'msg' => '质检完成',
                    'data' => ['record_id' => $recordId],
                    'time' => time()
                ]);
                
            } catch (Exception $e) {
                Db::rollback();
                throw $e;
            }
            
        } catch (Exception $e) {
            \think\Log::error('executeQualityCheck - 质检失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '质检失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 获取质检记录详情
     */
    public function getQualityRecordDetail()
    {
        try {
            $recordId = $this->request->param('record_id');
            
            if (!$recordId) {
                return json([
                    'code' => 0,
                    'msg' => '参数不完整',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            $record = Db::name('scanwork_quality_record')
                ->alias('qr')
                ->join('fa_scanwork_report r', 'qr.report_id = r.id', 'LEFT')
                ->join('fa_scanwork_quality_standard qs', 'qr.standard_id = qs.id', 'LEFT')
                ->join('fa_user u', 'qr.quality_user_id = u.id', 'LEFT')
                ->field('qr.*, r.report_code, r.quantity as report_quantity, r.remark as report_remark, qs.name as standard_name, u.nickname as quality_user_name, u.username as quality_user_username')
                ->where('qr.id', $recordId)
                ->find();
            
            if (!$record) {
                return json([
                    'code' => 0,
                    'msg' => '质检记录不存在',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            // 解析JSON字段
            $record['check_results_array'] = json_decode($record['check_results'], true);
            $record['unqualified_items_array'] = json_decode($record['unqualified_items'], true);
            $record['unqualified_reasons_array'] = json_decode($record['unqualified_reasons'], true);
            
            // 处理用户名称
            $record['quality_user_name'] = $record['quality_user_name'] ?: $record['quality_user_username'];
            unset($record['quality_user_username']);
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => $record,
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getQualityRecordDetail - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 计算总体结果
     */
    private function calculateOverallResult($checkResults)
    {
        if (!is_array($checkResults)) {
            return 2; // 默认不合格
        }

        $hasUnqualified = false;
        $hasQualified = false;

        foreach ($checkResults as $category => $items) {
            if (is_array($items)) {
                foreach ($items as $item => $result) {
                    if ($result === '不合格' || $result === '有缺陷' || $result === '有毛刺' || $result === '有划痕' || $result === '有变形') {
                        $hasUnqualified = true;
                    } elseif ($result === '合格' || $result === '无' || $result === '无缺陷' || $result === '无毛刺' || $result === '无划痕' || $result === '无变形') {
                        $hasQualified = true;
                    }
                }
            }
        }

        if ($hasUnqualified) {
            return 2; // 不合格
        } elseif ($hasQualified) {
            return 1; // 合格
        } else {
            return 2; // 默认不合格
        }
    }

    /**
     * 获取不合格项目
     */
    private function getUnqualifiedItems($checkResults)
    {
        $unqualifiedItems = [];
        
        if (!is_array($checkResults)) {
            return $unqualifiedItems;
        }

        foreach ($checkResults as $category => $items) {
            if (is_array($items)) {
                foreach ($items as $item => $result) {
                    if ($result === '不合格' || $result === '有缺陷' || $result === '有毛刺' || $result === '有划痕' || $result === '有变形') {
                        $unqualifiedItems[] = [
                            '项目' => $category . '-' . $item,
                            '问题' => $result,
                            '严重程度' => $this->getSeverityLevel($result)
                        ];
                    }
                }
            }
        }

        return $unqualifiedItems;
    }

    /**
     * 获取严重程度
     */
    private function getSeverityLevel($result)
    {
        $severeResults = ['不合格', '有缺陷', '有变形'];
        $moderateResults = ['有毛刺', '有划痕'];
        
        if (in_array($result, $severeResults)) {
            return '严重';
        } elseif (in_array($result, $moderateResults)) {
            return '中等';
        } else {
            return '轻微';
        }
    }

    /**
     * 获取质检统计数据（小程序）
     */
    public function getQualityStatistics()
    {
        try {
            $type = $this->request->param('type', 'overview');
            $startDate = $this->request->param('start_date', date('Y-m-01'));
            $endDate = $this->request->param('end_date', date('Y-m-d'));
            
            $startTime = strtotime($startDate . ' 00:00:00');
            $endTime = strtotime($endDate . ' 23:59:59');
            
            switch ($type) {
                case 'overview':
                    // 总体统计
                    $data = $this->getQualityOverviewStats($startTime, $endTime);
                    break;
                case 'trend':
                    // 趋势分析
                    $days = $this->request->param('days', 30);
                    $data = $this->getQualityTrendStats($days);
                    break;
                case 'process':
                    // 工序统计
                    $data = $this->getQualityProcessStats($startTime, $endTime);
                    break;
                case 'defect':
                    // 不合格项统计
                    $data = $this->getQualityDefectStats($startTime, $endTime);
                    break;
                default:
                    return json([
                        'code' => 0,
                        'msg' => '未知的统计类型',
                        'data' => null,
                        'time' => time()
                    ]);
            }
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => $data,
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getQualityStatistics - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }
    
    /**
     * 获取总体统计数据
     */
    private function getQualityOverviewStats($startTime, $endTime)
    {
        // 总质检数
        $total = Db::name('scanwork_quality_record')
            ->where('check_time', 'between', [$startTime, $endTime])
            ->count();
        
        // 合格数
        $qualified = Db::name('scanwork_quality_record')
            ->where('check_time', 'between', [$startTime, $endTime])
            ->where('overall_result', 1)
            ->count();
        
        // 不合格数
        $unqualified = Db::name('scanwork_quality_record')
            ->where('check_time', 'between', [$startTime, $endTime])
            ->where('overall_result', 2)
            ->count();
        
        // 让步接收数
        $concession = Db::name('scanwork_quality_record')
            ->where('check_time', 'between', [$startTime, $endTime])
            ->where('overall_result', 3)
            ->count();
        
        // 合格率
        $qualifiedRate = $total > 0 ? round($qualified / $total * 100, 2) : 0;
        
        return [
            'total' => $total,
            'qualified' => $qualified,
            'unqualified' => $unqualified,
            'concession' => $concession,
            'qualified_rate' => $qualifiedRate
        ];
    }
    
    /**
     * 获取趋势统计数据
     */
    private function getQualityTrendStats($days)
    {
        $endDate = date('Y-m-d');
        $startDate = date('Y-m-d', strtotime("-{$days} days"));
        
        $startTime = strtotime($startDate . ' 00:00:00');
        $endTime = strtotime($endDate . ' 23:59:59');
        
        $records = Db::query("SELECT DATE(FROM_UNIXTIME(check_time)) as date, overall_result, COUNT(*) as count 
                              FROM fa_scanwork_quality_record 
                              WHERE check_time BETWEEN {$startTime} AND {$endTime} 
                              GROUP BY DATE(FROM_UNIXTIME(check_time)), overall_result");
        
        // 组织数据
        $dates = [];
        $qualifiedData = [];
        $unqualifiedData = [];
        
        for ($i = 0; $i < $days; $i++) {
            $date = date('Y-m-d', strtotime("-{$i} days"));
            $dates[] = $date;
            $qualifiedData[$date] = 0;
            $unqualifiedData[$date] = 0;
        }
        
        foreach ($records as $record) {
            if ($record['overall_result'] == 1) {
                $qualifiedData[$record['date']] = $record['count'];
            } else if ($record['overall_result'] == 2) {
                $unqualifiedData[$record['date']] = $record['count'];
            }
        }
        
        return [
            'dates' => array_reverse($dates),
            'qualified' => array_values(array_reverse($qualifiedData)),
            'unqualified' => array_values(array_reverse($unqualifiedData))
        ];
    }
    
    /**
     * 获取工序统计数据
     */
    private function getQualityProcessStats($startTime, $endTime)
    {
        $sql = "SELECT 
                    p.name as process_name,
                    COUNT(*) as total,
                    SUM(CASE WHEN qr.overall_result = 1 THEN 1 ELSE 0 END) as qualified,
                    SUM(CASE WHEN qr.overall_result = 2 THEN 1 ELSE 0 END) as unqualified
                FROM fa_scanwork_quality_record qr
                LEFT JOIN fa_scanwork_report r ON qr.report_id = r.id
                LEFT JOIN fa_scanwork_allocation a ON r.allocation_id = a.id
                LEFT JOIN fa_scanwork_process p ON a.process_id = p.id
                WHERE qr.check_time BETWEEN {$startTime} AND {$endTime}
                GROUP BY p.id, p.name
                ORDER BY total DESC
                LIMIT 10";
        
        $result = Db::query($sql);
        
        return $result;
    }
    
    /**
     * 获取不合格项统计
     */
    private function getQualityDefectStats($startTime, $endTime)
    {
        $records = Db::name('scanwork_quality_record')
            ->field('unqualified_items')
            ->where('check_time', 'between', [$startTime, $endTime])
            ->where('overall_result', 2)
            ->where('unqualified_items', 'neq', '')
            ->select();
        
        $defectStats = [];
        foreach ($records as $record) {
            $items = json_decode($record['unqualified_items'], true);
            if (is_array($items)) {
                foreach ($items as $item) {
                    $key = $item['项目'] ?? '未知';
                    if (!isset($defectStats[$key])) {
                        $defectStats[$key] = 0;
                    }
                    $defectStats[$key]++;
                }
            }
        }
        
        // 排序并取TOP10
        arsort($defectStats);
        $defectStats = array_slice($defectStats, 0, 10, true);
        
        return [
            'items' => array_keys($defectStats),
            'counts' => array_values($defectStats)
        ];
    }

}